02.11 這就是所謂的軟工聖經?

人月神話

IBM System/360系統之父 佛瑞德·布魯克斯(Frederick Phillips Brooks, Jr) 所著經典文集。 軟體工程的神品。40週年中文紀年版。

全球最大的軟件消費者(美國軍方)每年買數十億美元購買軟件,其購買直接使用的只有 2%,另外 3%需要一些修改,其他 95% 垃圾。他們顯然沒有很滿足客戶的需求。

完整程序

水平邊界以下,程序變成編程產品(Programming Product)。 這是可以被任何人運行、測試、修復和擴展的程序。它可以運行在多種操作系統平臺上,供多套數據使用。要成為通用的編程品。

垂直邊界的右邊,程序變成編程系統(Programming System)中的一個構件單元。它是在功能上能相互協作的程序集合,具有規範的格式,可以進行交互,並可以用來組裝和搭建整個系統。

當要做一個完整的程序需要 3 * 3 = 9 工作量。

3*3工作量

人月神話

當意識到進度的偏移時,下意識(以及傳統)的反應是增加人力。這就像使用汽油滅火一樣,只會使事情更糟。解釋如下:

人數和時間的互換僅僅適用於以下情況:某個任務可以分解給參與人員,並且他們之間『 不需要相互的交流 』。

人數與時間

當任務由於次序上的限制不能分解時,人手的添加對進度沒有幫助。

任務次數受限時,人與時間

一對一交流的情況下,三個人的工作量是兩個人的三倍,四個人則是兩個人的六倍。

以兩個人的工作量以此類推,則工作量按照n(n-1)/2遞增。(我覺得單純他只是評估溝通的成本)

不論在多短的時間內,聘請到多麼能幹的兩位新員工,他們都需要接受一位有經驗的職員的培訓。如果培訓需要一個月的時間,那麼三個人月將會投入到原有進度安排以外的工作中

添加新員工

添加更多人力,結果往往會是上述循環的重複。這簡直就是一種瘋狂、愚蠢的做法。

開發時間規劃如下:

1/3計劃

1/6編碼

1/4構件測試和早期系統測試

1/4系統測試,所有的構件已完成

二次成本遠遠高於其他開銷。因此,在早期進度策劃時,允許充分的系統測試時間是非常重要的。

人員的數量依賴於單個子任務的數量。分派較多的人手,計劃較短的時間,將無法得到可行的進度表。 自己解讀:所以儘量將工作獨立細分,減少溝通時間。

外科手術

在該小組中,最好的和最差的表現在生產率上平均為10:1;在運行速度和空間上具有5:1的驚人差異!

簡言之,$20,000/年的程序員的生產率可能是$10,000/年程序員的10倍。

成本的主要組成部分是相互的溝通和交流,以及更正溝通不當所引起的不良結果(系統調試)。

外科醫生

外科醫生。Mills稱之為首席程序員。他親自定義功能和性能技術說明書,設計程序,編制源代碼,測試以及書寫技術文檔

副手。他是外科醫生的後備,能完成任何一部分工作,但是相對具有較少的經驗。他的主要作用是作為設計的思考者、討論者和評估人員

管理員。外科醫生是老闆,他必須在人員、加薪等方面具有決定權

編輯。外科醫生負責產生文檔——出於最大清晰度的考慮,他必須書寫文檔

兩個秘書。管理員和編輯每個人需要一個秘書

程序職員。他負責維護編程產品庫中所有團隊的技術記錄。

工具維護人員。現在已經有很多文件編輯、文本編輯和交互式調試等工具,因此團隊很少再需要自己的機器和機器操作人員

測試人員。外科醫生需要大量合適的測試用例,用來對他所編寫的工作片段,以及對整個工作進行測試

語言專家。隨著Algol語言的出現,人們開始認識到大多數計算機項目中,總有一兩個樂於掌握複雜編程語言的人。這些專家非常有幫助,很快大家會向他諮詢。這些天才不同於外科醫生,外科醫生主要是系統設計者以及考慮系統的整體表現。而語言專家則尋找一種簡潔、有效的使用語言的方法來解決複雜、晦澀或者棘手的問題。

觀點的不一致由外科醫生單方面來統一

系統設計

概念的完整性要求設計必須由一個人。

系統的結構師,如同建築的結構師一樣,是用戶的代理人。結構師的工作,是運用專業技術知識來支持用戶的真正利益

如果出現了很多非常重要但不兼容的構想,就應該拋棄原來的設計,對不同基本概念進行合併,在合併後的系統上重新開始。

體系結構(architecture)、設計實現(implementation)、物理實現(realization)

架構師的交互準則與機制

結構師有兩個選擇:削減設計或者建議成本更低的實現方法。

牢記是開發人員承擔創造性和發明性的實現責任,所以結構師只能建議,而不能支配;

時刻準備著為所指定的說明建議一種實現的方法,同樣準備接受其他任何能達到目標的方法;

對上述的建議保持低調和平靜;

準備放棄堅持所作的改進建議。

開發第二個系統所引起的後果純粹的功能修飾和增強明顯不同,也就是說存在對某些技術進行細化、精煉的趨勢。由於基本系統設想發生了變化,這些技術已經顯得落後。(自己解讀:擔心故步自封,不追求進步)

一個可以開闊結構師眼界的準則是為每個小功能分配一個值:每次改進,功能x不超過m字節的內存和n微秒

總結:以上也就是說,當製作第二個系統,需要因應技術的演進,適當的做優化、以求系統的進步。

會議

周例會是每週半天的會議,由所有的結構師,加上硬件和軟件實現人員代表和市場計劃人員參與,由首席系統結構師主持。

如果達成了共識,非常好;如果沒有,則由首席結構師來決定

每週交流一次。因此,大家對項目相關的內容比較瞭解,不需要安排額外時間對人員進行培訓。

清晰地授予首席結構師決策的權力,避免了妥協和拖延。

我們會舉行年度大會,典型的年度大會會持續兩週。(如果由我重新安排,我會每六個月舉行一次。)

開發進行中

對於存有疑問的實現人員,應鼓勵他們打電話詢問相應的結構師,而不是一邊自行猜測一邊工作,這是一項很基本的措施

多交流

非正式途徑:清晰定義小組內部的相互關係和充分利用電話,能鼓勵大量的電話溝通,從而達到對所書寫文檔的共同理解。

會議:常規項目會議。會議中,團隊一個接一個地進行簡要的技術陳述。這種方式非常有用,能澄清成百上千的細小誤解。

工作手冊:在項目的開始階段,應該準備正式的項目工作手冊。理所應當,我們專門用一節來討論它。

產品測試

設立測試小組是使設計決策得以貫徹執行的必要手段,同樣也是需要儘早著手,與設計同時實施的重要環節

團隊組織

團隊組織的目的是減少不必要交流和合作的數量,因此良好的團隊組織是解決上述交流問題的關鍵措施。 減少交流的方法是人力劃分(division of labor)和限定職責範圍(specialization of function)。當使用人力劃分和職責限定時,樹狀管理結構所映出對詳細交流的需要會相 應減少。

每棵子樹所必須具備的基本要素。它們是:

任務(a mission)

產品負責人(a producer)

技術主管和結構師(a technical director or architect)

進度(a schedule)

人力的劃分(a division of labor)

各部分之間的接口定義(interface definitions among the parts)

編成的工作量

時間規劃

計劃

編制文檔

測試

系統集成

培訓的時間

因此,上述小型項目數據的外推是沒有意義的。就好像把100碼短跑記錄外推,得出人類可以在3分鐘之內跑完1英里的結論一樣。

計算機產品文檔

目標:定義待滿足的目標和需要,定義迫切需要的資源、約束和優先級。

技術說明:計算機手冊和性能規格說明。它是在計劃新產品時第一個產生,並且最後完成的文檔。進度、時間表

預算:預算不僅僅是約束。對管理人員來說,它還是最有用的文檔之一。預算的存在會迫使技術決策的制訂,否則,技術決策很容易被忽略。更重要的是,它促使和澄清了策略上的一些決定。

做什麼:目標。定義了待完成的目標、迫切需要的資源、約束和優先級。

做什麼:產品技術說明。以建議書開始,以用戶手冊和內部文檔結束。速度和空間說明是關鍵的部分。

時間:進度表

資金:預算

地點:工作空間分配

人員:組織圖。它與接口說明是相互依存的,如同Conway的規律所述:“設計系統的組織架構受到產品的約束限制,生產出的系統是這些組織機構溝通結構的映射。1”Conway接著指出,一開始反映系統設計的組織架構圖,肯定不會是正確的。如果系統設計能自由地變化,則項目組織架構必須為變化做準備。

目的。主要的功能是什麼?開發程序的原因是什麼?

環境。程序運行在什麼樣的機器、硬件配置和操作系統上?

範圍。輸入的有效範圍是什麼?允許顯示的合法範圍是什麼?

實現功能和使用的算法。精確地闡述它做了什麼。

輸入-輸出格式。必須是確切和完整的。

操作指令。包括控制檯及輸出內容中正常和異常結束的行為。

選項。用戶的功能選項有哪些?如何在選項之間進行挑選?

運行時間。在指定的配置下,解決特定規模問題所需要的時間?

精度和校驗。期望結果的精確程度?如何進行精度的檢測?

項目經理的任務是制訂計劃,並根據計劃實現。但是隻有書面計劃是精確和可以溝通的。

手冊、或者書面規格說明,是一個非常必要的工具,儘管光有文檔是不夠的。手冊是產品的外部規格說明,它描述和規定了用戶所見的每一個細節;同樣的,它也是結構師主要的工作產物。

規格說明的風格必須清晰、完整和準確。

用戶常常會單獨提到某個定義,所以每條說明都必須重複所有的基本要素,所以所有文字都要相互一致。這往往使手冊讀起來枯燥乏味,但是精確比生動更加重要。

項目所有的文檔都必須是該結構的一部分。這包括

目的

外部規格說明

接口說明

技術標準

內部說明

管理備忘錄。

總結:\t1. 必須做好手冊、外部規格書,定義好明確完整個功能\t2. 要有一定的寫作規範,文字相互一致。

未雨綢繆

新的系統概念或新技術會不斷出現,所以開發的系統必須被拋棄,但即使是最優秀的項目經理,也不能無所不知地在最開始解決這些問題。

為捨棄而計劃,無論如何,你一定要這樣做。

如何為上述變化設計系統,是個非常著名的問題,在書本上被普遍討論——可能討論得比實踐還要多得多。它們包括細緻的模塊化、可擴展的函數、精確完整的模塊間接口設計、完備的文檔

原因在於編寫的人和維護的人不同,若要減少缺陷修復的bug,測試用例做好,維護的人減少、接口減少(接口減少難以時間).

維護:維護總成本通常是開發成本的40%或更多。缺陷修復總會以(20-50)%的機率引入新的bug。

出現bug的數量是發佈時間的函數

修復工作遲早會失去根基,重新設計是完全必要的

干將莫邪

保管好自己的一套工具。實用程序、調試輔助程序、測試用力生產工具、處理文檔系統

測試規格說明

在編寫代碼之前,規劃說明必須提交給測試小組,詳細檢查說明的完整性和正確性。

階段(量子)要麼很大,間隔很寬 vs 小而頻繁,根據他們的模型,小而頻繁的階段很容易變得不穩定

分成三個部分。

針對遇到的大多數常規數據和程序主要功能進行測試的用例。它們是測試用例的主要組成部分。

數量相對較少的合法數據測試用例,對輸入數據範圍邊界進行檢查,確保最大可能值、最小可能值和其他有效特殊數據可以正常工作。

數量相對較少的非法數據測試用例,在邊界外檢查數據範圍邊界,確保無效的輸入能有正確的數據診斷提示。 修改程序。調整程序或者修復程序需要更多的信息。顯然,這要求瞭解全部的細節,並且這些細節已經記錄在註釋良好的列表中。和一般用戶一樣,修改者迫切需要一份清晰明瞭的概述,不過這一次是關於系統的內部結構。那麼這份概述的組成部分是什麼呢?

流程圖或子系統的結構圖,對此以下有更詳細的論述。

對所用算法的完整描述,或者是對文檔中類似描述的引用。

對所有文件規劃的解釋。

數據流的概要描述——從磁盤或者磁帶中,獲取數據或程序處理的序列——以及在每個處理過程完成的操作。

初始設計中,對已預見修改的討論;特性、功能回調的位置以及出口;原作者對可能會擴充的地方以及可能處理方案的一些意見。另外,對隱藏缺陷的觀察也同樣很有價值。

總結:開發時間間隔夠寬、編碼前需要測試小組,詳細檢查說明的完整性與正確性。

禍起蕭牆

減少角色衝突,鼓勵狀態共享:

猛地拉開地毯: 兩者都為監督檢查目前工作進度,以PERT圖建立里程碑,里程碑越清楚越好,且時時檢查,若有延遲則即時提出解決方案。

PERT圖

總結:必須先定義好 PERT 圖與里程碑,時時檢查目前進度,並且時時解決方法。

沒有銀彈

產品目的

仔細地進行市場調研,避免開發已上市的產品。

開發過程

在獲取和制訂軟件需求時,將快速原型開發作為迭代計劃的一部分。

有機地更新軟件,隨著系統的運行、使用和測試,逐漸添加越來越多的功能。

不斷挑選和培養傑出的概念設計人員。

購買和自行開發。構建軟件最可能的徹底解決方案是不開發任何軟件

以上提到的任何軟件,購買都要比重新開發要低廉一些。即使支付100,000美元,購買的軟件也僅僅是一個人年的成本。而且軟件是立即可用的!至少對於現有的產品、對於那些專注於該領域開發者的成果而言,它們是可以立刻投入使用的

人才

尋求培養卓越設計人員的途徑。傑出的設計人員和卓越的管理人員一樣重要,他們應該得到相同的培養和回報。不僅僅是薪資

儘可能早地、有系統地識別頂級的設計人員。最好的通常不是那些最有經驗的人員。

為設計人員指派一位職業導師,負責他們技術方面的成長,仔細地為他們規劃職業生涯。

為每個方面制訂和維護一份職業計劃,包括與設計大師的、經過仔細挑選的學習過程、正式的高級教育和以及短期的課程——所有這些都穿插在設計和技術領導能力的培養安排中。

為成長中的設計人員提供相互交流和學習的機會。

讀書總結

目錄

開發流程

人力安排

人才培育