6 4 工資程式成長記 類與物件

2021-09-22 17:27:47 字數 3218 閱讀 8706

所謂需求分析,就是搞清楚客戶到底要的是乙個什麼樣的軟體。無論這個軟體是用於飛天登月的大型系統,還是僅供孩子們玩的遊戲程式,需求分析永遠都是我們開發工作的第一步。所以,當小陳接到老闆下達的任務後,他做的第一件事不是立即修改程式**,而是先進行需求的分析,搞清楚老闆到底要的是怎樣乙個工資程式。

根據老闆的抱怨(在實際的開發實踐中,這往往來自前期的使用者調查),這個工資程式必須能夠輸入員工的工資資料,而輸入資料又包括直接從資料檔案讀取和手工輸入;完成資料輸入以後,這個程式還要對工資資料進行處理,包括統計最高的工資,以及根據員工的姓名對工資進行查詢;最後,就是將所有的工資資料輸出到檔案,以便於下次直接讀取。

經過這樣的簡單需求分析,小陳對老闆想要的工資程式就比較清楚了。為了讓這些需求更加清晰而直觀,小陳將其繪製成了uml用例圖,老闆要的工資程式,不過就是實現了這些用例的工資程式。

最佳實踐:全世界程式設計師都在說uml

uml(統一建模語言,unified modeling language),一種描述軟體的常用方式,它通過為軟體建立模型,並通過一系列圖(用例圖、類圖、活**等)來直觀地描述軟體的結構和行為,從而讓程式設計師對軟體有乙個清晰的認識和理解。因此,在具體實現乙個軟體之前,我們都使用它來描述我們即將開發的軟體,以期在專案團隊中達成對軟體的共識。也正因為如此,整個專案團隊中的成員,甚至是全世界的程式設計師,都必須掌握這門建模語言。

圖6-13 工資程式的用例圖

完成程式的需求分析後,小陳明白了自己要做的是怎樣的乙個軟體,接下來的問題就是怎麼做了。按照物件導向思想解決問題的一般順序,首先就是從問題描述中發現物件。而小陳知道,問題描述中的那些名詞實際上就是物件。

按照「尋找物件就是尋找名詞」的思路,小陳開始尋找這個問題描述中的名詞。首先,遇到的第乙個名詞是工資系統(salarysys)。然後就是該系統所管理的員工(employee),因為級別的不同,員工又分為高階員工(officer)和普通員工(staff),這些就是整個問題中的名詞,也就構成了整個問題所涉及的物件。

從問題描述中除了可以找到物件之外,還可以發現物件之間的各種關係:工資系統管理員工物件,它們之間是一對多的關係;同時,高階員工和普通員工同屬於員工,這就表示它們應該有著共同的基類,都是從員工類所派生出來的。圖6-14描述了整個問題中的物件及物件之間的關係。

圖6-14  工資程式中的物件及物件之間的關係

在找到物件之後,就可以進一步分析這些物件所擁有的屬性和行為,然後利用物件導向的封裝機制將其封裝成具體的類。首先,分析這個問題中最基礎的員工類employee。根據老闆的要求,為了找到工資最高的員工,我們必須記錄每個員工的姓名(m_strname);為了根據在職時間(現在時間減去入職時間)動態地計算員工的工資,我們必須記錄員工的入職時間(m_nyear);員工有級別的差別,各個級別的員工工資計算方式不同,應該有乙個屬性級別(m_nlevel)來記錄。所以這個物件必需的屬性就是姓名、入職時間和級別。

分析了員工類employee的屬性,那麼它又該擁有什麼樣的行為呢?類的行為都是用來完成需求分析中的用例的,所以,employee類的行為跟它要完成的用例密切相關。為了完成「計算最大值」用例,它應該有乙個計算工資的行為(getsalary()),可以根據員工的在職時間動態地計算員工的工資。但是,employee類作為具體的員工類officer和staff的基類,並不知道工資的具體計算方法,所以這個行為只是乙個介面而已,需要留待它的派生類來具體實現,所以在employee中這個函式應該是乙個純虛函式;而要計算工資,它又必須知道員工的在職時間,所以它還必須有乙個獲得在職時間的行為(getworktime());同時,為了完成「查詢工資」這個用例,程式需要知道員工的姓名,所以員工類應該提供乙個獲得名字的行為(getname());最後,為了完成「輸出資料到檔案」的用例,employee類還必須提供獲得員工級別(getlevel())和入職年份(getyear())的行為,從而可以獲取員工的資訊並將其輸出。

圖6-15 employee類的屬性和行為

具體的員工類officer和staff是employee的派生類,在employee類的基礎上,這兩個具體的員工類並沒有額外的需要描述的內容,所以它們不需要新新增屬性,只需要從基類繼承已有的屬性即可。而至於行為,具體的員工類需要負責具體的工資計算和返回不同的員工級別,所以它們需要實現基類中的getsalary()和getlevel()這兩個虛函式。經過這樣的分析,officer和staff類應該具備的屬性和方法就很清楚了。小陳將它們用如下的uml類圖來表示:

圖6-16 officer和staff類的屬性和行為。

按照同樣的方法,小陳接著分析用於管理這些員工物件的salarysys類。為了儲存和管理多個employee物件,salarysys類必須有乙個陣列來儲存這些物件,而為了應用物件導向的多型機制來動態地計算員工工資,陣列中儲存的不應該是這些物件本身,而應該是指向這些物件的指標;同時,陣列只是表示了salarysys所能夠儲存的最多的物件指標,但是並不是陣列中的每個指標都是有效的,具體儲存了多少個指標還不清楚,我們還必須用乙個屬性來表示當前有效的指標的個數(m_ncount);另外,salarysys需要從檔案讀取資料,最後還需要將資料寫入檔案,所以它還需要乙個記錄資料檔名的屬性(m_strfilename)。

在salarysys類的行為上,小陳還是同樣從它要完成的用例來分析。根據他之前對這個程式進行的簡單需求分析,salarysys首先需要完成「輸入資料」這個用例,而這個用例又包含了「從檔案讀取」和「手工輸入」這兩個用例,這就要求salarysys類應該具有從檔案讀取資料(read())和讓使用者手工輸入(input())的行為;完成「輸入資料」之後,就是「處理資料」,它也同樣包括了「計算最大值」和「查詢工資」兩個用例,這就要求salarysys類具有查詢所有工資資料中的最大值(getmax())和根據使用者輸入的姓名查詢相應工資資訊(find())的行為;最後,就是「輸出資料」這個用例,它要求salarysys具有將所有工資資料儲存到資料檔案(write())的行為。

分析完成之後,小陳同樣將分析結果繪製成了uml類圖:

圖6-17 salarysys類的屬性和行為

程式設計師成長之旅 類和物件中篇

析構函式 拷貝建構函式 賦值運算子過載 const成員 取位址及const取位址運算子過載 如果乙個類中什麼都沒有,我們都知道它是空類,但是空類是不是什麼事情都不做,答案當然是否定的,它會生成6個預設函式。概念建構函式是乙個特殊的成員函式,名字與類名相同,建立類型別物件時由編譯器自動呼叫,保證每個資...

黑馬程式設計師 類與物件

asp.net android ios開發 net培訓 期待與您交流!建立某個特定的類的物件之前,objective c編譯器需要一些有關該類的資訊,尤其是物件的資料成員及其提供的功能。可以使用 inte ce指令把這些資訊傳遞給編譯器。import 類的宣告 inte ce person nsob...

黑馬程式設計師 OC中類與物件 語法雜記

培訓 學習型部落格,請多指教 簡單的說物件就是封裝了的資料和方法,類就是模版。類載入 當程式啟動時,會載入專案中所有的類和分類,而且載入後會呼叫每個類和分類的 load方法,而且只會呼叫一次。並且類一旦載入到記憶體,就不會被 直到程式結束的時候才會被 這個過程就叫做類載入。當第一次使用某個類建立物件...