讀完《軟件工程》和一些有關資料后,感覺一些東西都曾經接觸過,但在實際工作中有些理論要完全遵循可能還有些障礙,軟件工程只是提供了理論上的一些結論,但對項目的具體可操作性的規范的制定方面卻做的很少,《軟件工程》發展了幾十年,光是開發模型就達到了10多種,對不同的項目采用合適的開發模式,有些項目在不同的開發階段可能還要轉換開發模式,把它們靈活的應用到實際中還是很困難的。現在國內外都重視《軟件工程》是因為,人們都認識到了如果能夠適當合理的利用軟件工程的理論可以減小開發成本和風險,風險降低了,成本就減少了,利潤就提高了,所以有一種說法就是“軟件工程就是提高軟件項目利潤的理論”。但人們也都意識到《軟件工程》的確更接近于理論,它所提供的可操作性太差,于是就有了現在流行的RUP和XP開發理論,這兩種理論就是根據《軟件工程》的理論經過大量的試驗總結出的比較成功的開發模式,但RUP對于大項目還適合,對于小項目則不利于降低開發成本,所以現在國外最受歡迎的是XP。現在國內也開始使用這種方法,這種方法與其他開發方法最大的不同是將測試提到了一個幾乎是最重要的位置,先寫測試用例,然后編碼,而且在測試過程中提倡使用一些自動化的測試工具,如對Java測試的Junit和對Delphi測試的Dunit。如今的軟件工程已經改變了很多,提倡能夠快速適應客戶需求變化并能夠根據變化快速轉變開發方向的開發方法,國內外充斥著大量的討論能夠提高開發速度、減少需求變更的開發模式的書籍,如一些認證,如ISO9000,CMM,CMMI等,還有開發模式,如敏捷開發,RUP,XP,PSP,TSPi等。在一定情況下,XP是很出眾的,XP對國情是否適合可能尚難以下結論,但XP對于測試的重視和對使用自動化測試工具的推崇則是我們可以借鑒的。
無論是在上個世紀還是在現在,軟件開發所涉及的工作基本上都沒有變化,它們都起始于一個實際需要或某個靈感,然后就是分析,設計,編碼,調試,維護。這些任務以某種方式動態地結合起來就構成了軟件開發的整個過程,這就是所謂的“軟件開發周期”。 但對于這些工作,具體怎樣做,什么時候做,每個人都有自己的一套方式,甚至有的人有幾套方式。這樣,當幾個人合在一起干活的時候,最終的結果就只能是一片混亂。所以就需要一套規則,大家都按規則來辦事,問題就會少得多。好的規則就叫做規范,規范都是由一些有經驗的前輩根據經驗總結的,又經過長時間的歷練,不斷地被補充修正,可以說都是精華,按照規范來干活,對于提高軟件質量和工作效率自然大有幫助。而軟件工程,用通俗的話講就是,一套用于軟件的團隊開發,以提高軟件質量和程序員工作效率為目的的規范。其核心就是,對于軟件開發的5個重要組成部分:需求分析,設計,編碼,調試,維護,如何組織這5個部分的工作,以及如何完成每一個工作。簡單來說,就是對于總體的組織和對于局部的實現。
規范只是提供一個好的例子,以描述一種思想,具體到每一個環節怎樣實現,對于不同的公司或團體則是各有千秋,因為根本就不可能存在一套放之天下皆可行的標準。就像C++,也只是提供了一套標準,不同的編譯器都有各自的實現,對標準的支持程度也互不相同。所以,在不同的公司或團體中,盡管核心思想都是大同小異,但具體到每一個步驟,往往都是不相同的。
我個人認為軟件工程很重要,但更重要的是要能夠根據不同的項目在不同階段選擇合適的開發模式,規避風險,適應客戶靈活多變的需求變更。所以對需求調研和需求分析提出了更高的要求。我看過了一些討論軟件工程的文章,幾乎一致認為“客戶直接參與的項目成功的可能性非常高”,傳統的軟件工程中提出的不論是“瀑布”還是“螺旋”模型都是進行階段性的客戶確認再開發,等開發完或者客戶的需求變了,或者需求分析有錯誤,完全符合客戶要求的幾乎沒有。所以我們是否考慮一下能否在條件允許的情況下,在以后的項目的開發中多征求客戶意見,而不是在一階段完成后再請客戶看,這有利于我們降低開發大規模修改的風險。這也是“極限開發”模式中很重要的一點。當然這也不是絕對的,但這是經過證實的成功率比較高的一種方式。
在前期需求調研和需求分析都做好了之后,就可以做概要設計和詳細設計了,我認為這部分很關鍵的一點是確定界面風格和關于代碼復用的考慮。一個符合客戶習慣的界面是最保險的方案,這里面包括客戶的操作習慣和審美習慣。但對開發人員更需要注意的是代碼復用,一個好的代碼應該是注釋詳細、代碼可讀性強、代碼復用率高的集合。而要做到代碼的高復用率需要高度的抽象能力和對類的粒度的劃分,對于粒度的劃分應該遵循很多教材上多次提到的“高內聚,低耦合”,也就是說一個函數或方法的功能越單一越容易被組合起來復用,和其他的方法或函數或其他類的關聯越少越好,這樣在與之關聯的對象或方法改變后不需要改動或很少改動就可以被復用。
另外“設計模式”也是很重要的,“設計模式”為開發人員提供了一系列其他人經過多次試驗證實成功的可以放心使用的解決套路,能夠按照“設計模式”的思路開發系統可以獲得很好的擴展性和強壯性,這也是經過無數案例證明過的。舉個簡單的例子,如果將獲得數據的部分和顯示數據的代碼混在一起,如果將來在改動顯示部分或改動獲得數據部分則要到混在一起的代碼中去挑自己要改動的部分,這可能造成不該動的代碼被改動了,或者因為一部分改動了,另一部分必須被改動,這樣也帶入了被迫改動代碼的正確性的問題。對于這樣的改動需要在測試時增大測試力度,才能保證代碼是正確的,當然這是以增大測試成本為代價的。用另一種方式,使用設計模式,遵循MVC模式,將獲得數據部分作為C(控制部分)封裝在一個函數里,將顯示部分作為V(視圖)封裝在另一個部分,他們之間的數據傳遞用函數的參數或其他數據結構(如記錄、集合等),這樣就可以保證改動一部分不會影響另一部分的正確性,測試時只要針對改動的部分測試就可以了,不會因為不知道是那部分出現的錯誤而做更多的測試用例來確定錯誤來源。
軟件維護也是個重要的階段,軟件在運行一階段后,可能會發現一些測試時沒測出的錯誤,也可能客戶覺得有些地方改變一下會為他們的工作提供更多的方便,這是就需要軟件維護。這時需要的開發人員不會很多,但這時維護人員可能不是原來的開發人員,這是就設計到了代碼的可讀性和可維護性。良好的代碼應該有詳盡的注釋,當然最好還要有簡單明了的文檔。維護后應該有維護記錄,要說明維護原因,變更部分的說明。如果在維護階段不知道原來的代碼的意義,則維護工作根本無處著手。我在維護南昌市民卡項目過程中遇到這樣一件事,因為南昌方面急著要操作員卡,而這邊制卡程序需要改動,但這邊什么文檔都沒有,程序沒有業務方面的注釋,根本看不出什么意思,只好重做。如果當時有一份良好的注釋,可能重新開工的可能就機會沒有了。
另外功能齊全的公用單元有利于減少開發重新編寫的代碼量,可以節省開發時間,增強代碼的復用性。這在多個項目中可以看到好處,能夠非常迅速的就搭建起了系統框架,對于一些功能需要的技術實現已經在公用單元提供了,所以可以拿過來直接使用。
如何組織軟件開發過程中的每一個步驟,就是軟件開發周期模型要解決的問題。我認為開發軟件,其實就像是解決一個邏輯問題。想想自己平時是怎樣寫程序的。首先是要有一個想法,即我寫的這個程序是要干什么的;然后就是對要實現的核心功能大概構思一種或多種實現方法,并從中選出一種自認為是較好的;接下來就是將涉及的各種主要或次要功能分成各個模塊;最后就是分模塊來編碼和差錯。在我看來,除了第一步外,其余的步驟應該是一個循環的過程。在編碼的過程中,你總是需要不斷地回過頭來修改原先的模塊設計,甚至最初選定的實現算法。除非你是先知,否則,對于一個具有一定規模和復雜度的軟件來說,在“設計—編碼”這個過程中,實在有太多的不可預知性和變化性,你根本不可能全盤地把握住每一個細節。那么,對其每一個步驟的組織,即周期模型,就必須包容它的這種性質。現在來看一下瀑布模型。瀑布模型是一種線性模型,其最大的特點就是簡單直觀。它將軟件開發過程規劃為“分析—設計—編碼—測試—維護”的線性過程,也就是說,你必須首先把你的軟件要干的每一件工作都分析得徹徹底底,再對每一個模塊,每一個接口,事無巨細,都設計得非常完美,然后才開始編碼的工作,并且在編碼的時候就像在對著圖紙砌模型,根本不用再回頭作任何修改,當然,是在把所有的代碼都寫完以后才開始測試的。
軟件開發過程的實現具體到每一步的工作要怎樣完成,我前面已提到過,是非常靈活的,只要把握住大體的方向就行。在進行分析,設計,編碼,調試,維護這幾部分的工作的時候,最核心的就是文檔的編寫。文檔的作用在于以下3個方面:一是可以幫助整理思路。把要完成的目標,系統的結構,每一個模塊的功能等整理一下,然后分門別類地寫下來,這樣在開發的過程中,就有據可依,在需要回過頭來修改設計的時候,也有證可考。二是便于交流。在腦子里的東西一多,就會散而且亂,用語言表達的時候,很容易會丟三落四,別人也很難把握住你的思想。但經過整理寫在紙上以后,則會清晰得多,無論是別人還是自己,看起來都可以一目了然。三是可以作為以后維護時的參考資料。有一句名言:“筆和紙永遠都比大腦可靠”,意思就是說,放在大腦里的東西說不準哪天就忘了,但寫在紙上的東西,只要不發生什么意外,一般是丟不了的。當過了一段時間,你需要再回過頭來修改你的程序的時候,你就會發現,你以前寫下的文檔實在太有價值了。別指望你的源代碼,對于復雜一點的程序來說,單純的源代碼幾乎會扼殺掉你所有的時間。可行性分析就是關于當前項目能不能干的分析結果。主要考慮的方面包括:是否能把這個項目開發出來;假如可以的話,預計需要多少時間,能否滿足客人的時間要求;需要多少人力和資金的投入;最重要的是,這個項目能否賺錢,能賺多少。還要對可能存在的風險進行評估。項目描述這是在決定立項以后,對當前項目的一份扼要說明。必須包括以下幾個方面:(1)項目的名稱或編號;(2)對客戶方的描述;(3)對開發人員的描述;(4)工程任務的描述;(5)工程的輸入和輸出;(6)開發環境;(7)其他的附加條件。
通過對《實用軟件工程》和一些資料的學習,受益匪淺,對軟件開發有了一個系統的了解,對一些概念有了一定了解,雖都這些是些理論,可能在實際工作中很少用到,理論知識用于指導實踐,親身體驗才能領悟軟件工程的妙用。我感覺到學習這門課需花費大量的時間思考,從而換取了寶貴的經驗。學習軟件工程的過程是枯燥的,但我認為若把這些枯燥的理論學好,在將來的學習和工作中一定會有益。










