軟體工程
軟體開發的管理
[編輯]最近讀了關於微軟的軟體開發模式的資料,又讀了關於「極端編程」的資料。了解了現代企業的現代管理模式。「極端編程」是指軟體開發的極端狀態,也就是理想狀態。微軟的方法更具體,「極端編程」在開發過程中各方面人員的相互交流方面更成熟。總體上兩種方法在大的方面都是雷同的。
關於微軟的開發模式的資料可以參考《微軟的秘密》,關於極端編程的資料可以參考 http://c2.com 。
綜合兩者,簡述一下軟體開發的方法。
保證開發計劃按時完成和產品質量的方法:
開發要完成的內容是根據用戶的需要確定的。在微軟是由銷售人員確定用戶需求。這裡主要說明「極端編程」的方法。在極端編程中,用戶確定要開發的功能,用戶可以把對自己更重要的功能放到前面先完成。開發人員對這些功能提出每個功能實現的時間,用戶如果認為時間太長可以取消一些功能。這樣,通過這種協商和反饋,保證了開發的最大價值。同時,因為是開發人員確定功能實現的時間,因此,計劃必要容易按時完成。特性不要要求太具體,要簡單勾勒。
實際上,用戶開始不知道自己需要什麼,這需要開發人員研究用戶行為,提出可以實現的效果,用戶對效果進行評價和修改,來確定開發的目標。當開發完成時也要提供給用戶進行試用,獲得反饋意見,對產品進行改良。這也是和用戶不斷交流的過程。這種交流保證了產品確實是用戶需要的。
對於每項功能,由開發的組織者和開發員討論制定詳細的完成步驟,確定每一部分要達到的具體效果,寫詳細的文檔,描述每個界面完成的外觀和函數的功能。這叫任務引擎。任務引擎不是一次寫成的,可以隨時間不斷詳細化。
根據任務引擎再編制詳細的時間計劃,將任務引擎劃分為若干個任務,每個任務由一個人負責,這個時間計劃要由每個具體的開發人員提出或協商每個任務和每個任務的具體部分的完成時間,這個時間計劃要細分到半天至三天,至少一個星期。在每項任務的完成時間後面要留有緩衝時間以應付意外情況和時間估計的不准確。只有計劃的時間單位的細化才能保證任務的完成在完全的掌握中。
在時間計劃中有界面凍結時間、文檔凍結時間、代碼凍結時間,這樣保證了計劃的相互關聯的部分不會影響計劃的完成。
開發部門和測試部門是相互獨立的部門,幾乎每個開發人員對應一個測試人員,兩者的人數是1:1。要求開發人員每天把完成的代碼放到伺服器上,每天測試人員進行昨天完成的代碼的測試以及以前代碼的測試,並將發現的問題發到伺服器上,反饋給開發人員。有時因為發現的問題太多,管理人員會發現開發的難度,因此會取消部分任務和開發。測試人員和開發人員要完成的工作都有詳細的規範,規定具體要完成的內容。通過專業的測試,保證了軟體的質量。
在開發中,管理人員要追蹤計劃的完成情況,及時發現問題,指導問題的解決,保證計劃完成,根據問題調整計劃。
微軟把每個軟體版本的開發過程分為幾個里程碑,大概每兩三個月一個里程碑,每個裡程碑實現部分的特性(軟體功能。在微軟,軟體功能被成為特性。)。最重要最基礎的特性放到前面的里程碑中,不重要的特性放到後面的里程碑中,這樣,如果要保證軟體的按時發布,最後可以刪掉一些不重要的特性保證軟體的按時發布。每個裡程碑都要在公司內部和外部進行軟體的發布和各種公共測試,保證了用戶的反饋和這部分功能的最後穩定。這樣,避免了到軟體發布的最後時期才進行各種公共測試的被動。也加大了和用戶交互的機會。
在每個裡程碑中,一般都留下三分之一的緩衝時間,來應付各種開發的意外情況,使開發工作可以從容完成,如果到了緩衝時期,為了保證計劃的完成有可能取消一些不必要的功能。緩衝時間在「極端編程」中稱為「時間因子」。
這些方法實現比較複雜,但這是已經有大量工程和公司的實踐。不是理想的空中樓閣。針對具體公司,根據自己的管理條件,可以分批逐步實現。或者沒有能力實現,也可以參考先進的專案管理方法,認識到自己管理上的各種問題產生的原因,有一個管理的目標。
參照軟體的專案管理,建築的專案管理是相同的
[編輯]建築項目採用設計與施工分離的方式,從而強化了設計與需求分析的過程。
現在通過效果圖的方式,加強了和用戶的交流。
初設和司令圖就相當於任務引擎。相對於任務引擎的細化,在基礎設計階段要完全做好相互間的資料配合,所有協調工作首先完成。
現在以卷冊為計劃單位,太粗,常常不能保證計劃完成。應該計劃細分到概念設計、計算書、提資、圖紙。在每個階段同時校核。從設計初期,就一對一校核。能及時發現問題,及時解決。同時要加強追蹤力度。
里程碑使整個工程的完成有一個清晰的思路。
各種互提資料的凍結時間,可以保證配合順利。
先進的人事管理的幾個要點
[編輯]每個人管理的人員適當的人數是8個。這樣才不會導致交流瓶頸。
扁平式管理:就是打破上下級關係,不只是垂直交流,而是大力推進越級交流和平級之間的相互交流協作。增強水平聯繫,減少垂直聯繫。儘量減少辦事的環節。
不強調等級,管理人員也是普通人員,不以職位的高低評價,以業績來評價。職員的業績如果好,甚至可以超過經理。
採取多線晉升制,管理線、技術線等平行發展,使人根據自己的條件選擇發展方向。
職位升降、獎勵多少、淘汰率都根據業績評價來決定,有專門的小組進行業績評價。並且業績評價不是按年,而是至少按月。這樣才能隨時保持員工的壓力和動力。
建立強有力的中層管理層來保證各種企業功能的順利完成。
對企業有完善的監督機制,保證經營方向決策的科學性。
極限編程(eXtreme Programming,XP)的特點
[編輯]XP在很多方面都和我們傳統意義上的軟體工程不同,同時,它也和傳統的管理和項目計劃的方法不同。這些方法在軟體工程和其他管理活動中都有借鑑意義。
特點如下:
不採用瀑布式的軟體工程方法,而採用原型法。將一個軟體開發項目分為多個迭代周期,每個周期實現部分軟體功能。在每個周期都進行提出需求、設計軟體架構、編碼、測試、發布的軟體開發的全過程。每個周期都進行充分的測試和集成。這樣的好處是可以不斷的從客戶方面得到反饋,更逼近實際的軟體需求。通過頻繁的重新編碼的過程,可以非常適應功能更改的需求,同時增加軟體的易維護性。在不斷的迭代中,避免架構設計的重大失誤造成的軟體不能如期交工,避免了軟體設計的風險。
在軟體設計中,強調簡單性,就是堅決不做用不到的通用功能。同時,也不刻意避免重新編碼,只有不斷的重新編碼才能保證軟體的合理性。不害怕對整個軟體推倒重做。認為重新編碼是很正常的現象。每次的重新編碼都會大大減少軟體中的熵值。
在專業分工中,提出在開發團隊中要有全職的客戶人員的參與,同時在軟體團隊中也要有自己的領域專家。這樣,可以和客戶充分交流,徹底了解應用需求。這種軟體需求的提出不是一次性的,而是不斷的交流。
也有專門的軟體架構的設計師,首先進行軟體整體架構的設計。這種設計一般使用UML語言。
在軟體開發的順序上,和傳統方法完全相反。傳統方法是按照整體設計、編寫代碼、進行測試、交付客戶的方法。而XP是按照交付客戶、測試、編碼、設計的順序來開發。首先將要交付客戶的軟體的界面作出來,先讓客戶對軟體有實際體驗,這樣,可以獲得客戶的更多的反饋,使需求可以在開發前確定。在編碼前就先把測試程序做好,這樣,編碼完成後就可以馬上進行測試。通過不斷的測試來保證軟體的質量。在進行軟體架構設計之前就進行編碼,可以使問題更早暴露,可以使最後的軟體設計更體現編碼的特點,更符合實際,更容易實現,也保證了設計的合理,保證了軟體設計的大量決定的正確性。
在項目計劃的實現上,每次的計劃都是技術人員對客戶提出時間表,由最後的開發人員對項目經理提出編碼的時間表。這種計劃都是從下而上的,不是從上到下的,更容易保證計劃的按時完成。同時,多個迭代周期也使工期的估計越來越精確。
在分工上,強調角色輪換,項目的集體負責,分工的自願性。分工的自願性就是每個人的工作內容不是由項目經理分派,而是由每個人自願領取,這樣保證了每個人可以發揮自己的特長,適應自己的情況。當然,在每個問題上都要有唯一的決策人,同時,也要經過充分的交流和溝通。角色輪換就是在項目中,一個人在不同的周期中擔任不同的角色,可以保證每個人對項目的整體把握,方便項目中的溝通和理解。項目的集體負責,就是每個人不是完成自己的工作就可以了,要對整個項目的完成負責,任何人都可以對工作的任何部分提出自己的建議。任何人都可以從事任何工作。任何人都要對整個項目熟悉。這樣做的優點是可以充分的鍛鍊人、可以發揮每個人的積極性、可以使項目不依賴於某個特定的人,方便今後的軟體的維護,通過工作內容的變換可以提高人工作的興趣。通過角色輪換還可以使每個人都勞逸結合,方便相互理解,避免由於不理解而造成的各種配合問題。
保證8小時工作制,避免加班。
(我加幾條:要有充分的培訓、要有每個人的提升空間、制定報酬要根據對企業的貢獻大小,而不是職位的高低,允許下屬比上級薪酬更高,薪酬的高低取決於績效評定,同時績效評定要儘可能量化。並且推行淘汰制。同時有有效的招聘制度。有強有力的後勤保障制度和輕鬆的企業文化。)
提出了成對編程的思路,就是每個模塊的編碼都是兩個人一起干,共用一台電腦。這樣,一個人編碼時,令一個人就可以檢查代碼,或對編碼的思路進行思考,寫文檔等。不再有另外的測試人員,兩個人同時完成代碼的測試,並且使先寫測試程序然後再編程。這樣避免了編程人員和測試人員的矛盾。也解決了一個人自己檢查的局限性。兩個人共同檢查可以避免大多數的錯誤。在共同編程中還可以進行經驗的交流和傳授。也避免了將一個工作一直幹下去的無聊,交流增加了情趣。並且兩個人共同工作也增加了工作量的彈性,使項目計劃的瓶頸工作能儘快解決。根據成對編程的思路,開發小組也可以分為兩個小組,一個小組進行開發,另一個小組作改進和bug修正等工作。也有同樣的效果。
在人員的分工上要靈活,要保證軟體開發中的角色的齊全,但每個角色可以由幾個人共同擔任,也可以一個人擔任幾個角色,並且在項目的不同時期,不同角色的人員數量會不斷變化。
每天或隔天,開一個站立會議(保證開會時間儘量短),來解決工作時間不一致和相互打擾工作的情況。在每個迭代周期也有一個計劃和分工等的全體大會。
XP的實施方法就要求能適應工作中出現的問題,不斷對XP進行改進,而不能照搬套用。
XP的目標就是發揮人的最大積極性,保證充分的交流。
XP的優勢是能很好的適應需求的更改、設計框架的更改。
XP採用和建立一個通常框架相反的方法來適應需求,而是儘量簡單。
軟體開發的流程
[編輯]對開源軟體來說, 首先是軟體功能的討論。 相互競爭的軟體的評價。 能否利用已有代碼。 軟體架構的討論,使用UML 開發人員的落實 開發中的相互交流
開源軟體項目的幾個問題
[編輯]啟動一個項目首先這個項目要滿足發起人的需求。就是要為了使用而開發,而不是為了開發而開發。只有項目能滿足自己的需求,這個項目才能堅持下去。如果開發是為了別人,這個項目的前景不妙。
開發的項目要有鮮明的特點,明確的訴求點。如果是和其他已有軟體功能相近,就加入其他項目,或建立一個已有項目的分支比較好。
不能只是因為語言的關係,就新建一個開發項目。重新學習一個新的語言花費的時間比新開發一個軟體要少的多。除非特別需要,做一個軟體的另一個程式語言的版本更好。儘量保證兼容。
一個項目最好做成國際版本。這樣,不但中國人能加入開發,外國人也能接手。這樣,項目的存活的可能就會高的多。
實際上,現在中國的開源項目,做一個國外項目的中文版本是最有效的,不但是翻譯,更重要的是解決所有的不兼容中文的問題。當然,還要保證雙向兼容。從雙向兼容的角度來說「中蟒」不是個好項目。
很多開源開發人員感覺既然是業餘搞,就想怎麼幹就怎麼幹。實際上,開源項目更應該講究效率,更應該講究效果。(效果和效率是不同的)。開源項目相對商業項目來說,人力更少,更應該考慮投入產出,考慮成本。所以,按照我上面說的幾點,會使開源的力量能得到更好的發揮。
一些商業軟體在開發過程中大量使用開源軟體的內容,但沒有遵循開源協議,實際上也是一種侵權行為。
聊聊軟體架構、程式語言、軟體、開發平台
[編輯]層次和組件
[編輯]軟體架構的一個重要概念是層次,通常軟體通過分層來達到靈活的發展。比如作業系統和其它軟體的分離,比如中間件的概念,比如網絡的7個層次。目前一個比較重要的層次概念就是表現、邏輯、數據的分離。
另一個重要概念是組件,組件並不是在vb語言發明後才出現的,unix的各個小程序通過管道、shell語言相互結合,實際就是組件的表現,程式語言的庫也符合組件的概念,com其實就是vb的特殊的庫。zope的product也是組件的一個典型。還有netscape外掛程式、winamp外掛程式等都是組件的概念。組件就是在一個平台上有很多相互獨立部分,這些獨立的部分可以分別安裝,最後通過膠水語言來調動各個組件共同完成任務。作業系統和其上面的各個應用程式就是組件模型的體現。目前尤其以com和java bean為典型。
程序規模的大小和程式語言
[編輯]程序越大,劃分的層次和組件就越多。但如果是小程序,應該從不分層次和組件開始。從小程序到大程序的發展過程,就是不斷的分層、分組件的過程。不同的程式語言對應的程序的規模不同。但因為不可能總是大程序,也不可能總是小程序,能適應各種不同規模的程式語言最好,以免要學習很多語言,並在很多語言之間轉換。比較能適應不同規模的語言是python,即照顧了函數型的小型程序,也照顧了物件導向的大型程序。perl、php是小型語言,java是大型語言。但對程序規模適應能力最強的是scheme,它編寫的最基本的語言甚至不用輸入輸出,也可以沒有數據和程序的區分,而最後scheme還有專門的對象、類、組件這些能適應大型程序的語言特徵。但是不是scheme做的不夠專業,我就不知道了,至少可能速度慢。
利用現成的庫還是自己實現庫功能
[編輯]我認為首先儘量自己實現所有的功能,只有必要的時候,或更進一步發展的時候才用他人的庫來實現自己需要的功能。因為自己實現的東西才最隨心所欲,可定製性更強,也不受他人庫的局限,獨立性也強。在原型設計階段,不要求穩定性和複雜功能的時候,全部的自己實現會儘可能簡單,而不受庫的限制而做很多額外的工作,和基本任務關係較遠的工作。
我剛剛完成的一個「文章交換」的程序就是一個較少借用外界功能的原型,用戶註冊等的功能都是從零開始自己完成的,在這個過程中,沒有學習和跟蹤cmf的知識也能完成程序。雖然最後有可能在cmf中實現,但獨立實現的樂趣很大,感覺很簡練,很純粹。還有一次在acad中用autolisp實現了一個類似unix的info的東西,另一次是在excel中用vba實現了一個文件轉換的程序,分別利用了acad和excel的輸入輸出功能,最後都感覺很羅嗦,感覺還是獨立出來最好。
最後結論是,如果能獨立就不要利用太多的庫,等程序發展了,有必要時在再成熟的庫來實現,程序獨立後往往很方便。試試脫離java、脫離zope、脫離kde來編程,看感覺如何。
程序的友好性和成熟性
[編輯]最開始很多用戶會選擇界面很友好的程序,喜歡程序自動幫你把很多事情都搞定。如果進一步深入,就會發現友好的自動的程序常常限制了你的手腳,並且沒有你需要的特定的功能,這是你就會尋找更專業的程序,最後更專業的程序常常是界面不友好的文本界面的,經過了十幾年發展的老程序。
前面所說的兩種程序實際對應著商業程序和開源程序。商業程序常常是友好的,但也是不成熟的,常常動不動就升版,但卻不能滿足你的需求,因為人們的需求太多了,軟體公司只能挑最主要的,另外,軟體公司還會不斷的緊跟潮流,推出新功能,這樣就可以賺到更多的錢,但也同時把熟悉老程序的用戶給拋棄了,也同時有很多雖然老,但很好用的功能給拋棄了,一個全新的開始也意味著從頭再來,這是bug最多,用戶需求的滿足也最少,商業公司的最終結局是破產,這是首先感到悲傷的是那些軟體的用戶,所有的使用經驗都全沒用了。
而開源軟體跟不上潮流,但發展了十幾年,有所有用戶想到的功能,也沒有沒完沒了的升級,因為它早就穩定了,也沒有破產的危險,因為它不需要盈利,另外,開源軟體經過了多年發展,核心會越來越小,功能會越來越專一,不同的程序之間會越來越默契,小而精,很純粹,不會出現「腫件」的情況。這些老的程序常常只能在unix上找到。在這裡推薦一個網址:http://learn.tsinghua.edu.cn/homepage/015450/ ,講的就是怎樣拋棄時髦程序,選擇老程序的過程。
選擇編程平台的層次
[編輯]選擇低層次的平台,比如c,容易發布,就是一個可執行程序,功能強大並靈活,但實現任務所需要的勞動很多。
選擇高層次的平台,如cmf,有大量的學習任務,但完成所需功能時鍵入的代碼少,另外,如果發布程序就要帶著python,zope、cmf。總是拖家帶口。
選擇什麼平台,就看你是要求功能還是要求開發速度。
本來我對組件的理解是和你一樣的,都是看到「com」--「組件對象模型」,認為它才是組件。但最近接觸了zope和scheme,zope的product也自稱組件編程,scheme的unit類也說實現了組件編程。再聯想到unix環境的大量小程序的協同工作。在我頭腦中,組件的概念就擴大了。
- 首先組件是相對於封閉的程序來說的,封閉的程序完全自己實現功能,而不能由第三方添加功能。如果一個程序提供一個接口,能被第三方添加功能,那麼這個程序就實現了一個組件環境。比如程式語言的庫,比如winamp的外掛程式,netscape的外掛程式。
- 如果這個程序本身的大量的功能都是在組件環境內實現的,和其它組件處於同樣的地位,而組件環境被精簡為一個核心平台,那麼可以說這個軟體是組件架構的。比如作業系統,比如作業系統的微核心結構。比如acad的ads環境,等等底層接口開放的軟體都是組件架構的環境。
- 如果組件都很專業,只實現專一的功能,並且有完備的接口,能很容易的組合到一起,並且通常由腳本語言,將各個組件組合在一起來完成最終的工作,那麼就可以稱作一個比較專業的組件環境,比如java bean,比如zope的product,比如scheme的unit。比如unix的shell環境。com的環境是最容易的,能夠以可視化的方式組合到一起。
- 如果組件可以由任何語言編寫,可以實現運行時的二進制的調用,並且一般經過了標準化,那麼就成為了標準化的組件環境,比如corba和com,比如soap。比如xmlrpc,比如apple的cocoa環境,比如.net。
上面就是我頭腦中的組件的概念,只有最後的組件的概念符合你的概念。
設立軟體項目的不同方式
[編輯]現在開源軟體很熱門,在很多人的觀念里講到軟體開發就是開源的方式。
下面討論一下開源的限定條件。
比如開源的開發者都是因為自己有使用的需求和空餘時間,並且對開發有興趣才參與開源項目的。
如果是自己有這方面的能力,並且開發出來的軟體對其他人很有用,而自己對相關的軟體不是特別有興趣。在這種情況下啟動一個開源項目是不可能的。但可能的方法一是辦一個商業軟體的公司,使自己的能力能夠為他人服務,也更多的發揮自己的特長,將本來做不擅長的工作的時間用來做擅長的工作。另一種方法就是成立基金會或尋求項目資助,尋求項目資助的往往是科研項目。基金會或科研立項的方式能夠產生一個大家都可用的成果,也保證了開發者的工作時間。不過基金會和科研立項的方法範圍比較窄,不能代替商業開發。
貢獻
[編輯]本文章最初作者是:tomz。tomz的網頁:http://tomz.126.com