《人月神話》讀書筆記

人月神話讀書筆記

焦油坑

為什么兩個(gè)人的創(chuàng)業(yè)團(tuán)隊(duì)可以超越大公司9倍以上的效率開發(fā)任何程序。而大公司的產(chǎn)業(yè)化團(tuán)隊(duì)效率只有1000代碼行/年

程序員,就像詩人一樣,幾乎僅僅工作在單純的思考中。程序員憑空運(yùn)用自己的想象,來建造自己的“城堡”。很少有這樣的介質(zhì)——?jiǎng)?chuàng)造的方式如此靈活,如此得益于精煉和重建,如此得容易實(shí)現(xiàn)概念上的設(shè)想。

評(píng)論:這個(gè)觀點(diǎn)與《黑客與畫家》中的觀點(diǎn)不謀而合,后者把程序員的工作看成和畫家、作家一樣的類似。但是也正因?yàn)槌绦騿T所做的工作是純粹的智力創(chuàng)造,不斷的推到重來就成為常態(tài)。概念設(shè)計(jì)上的不完善,使得軟件架構(gòu)變得越來越龐大、復(fù)雜并且難以為繼,成為一個(gè)焦油坑,越是掙扎,越是深陷其中。

人月神話

Brooks法則:

“向進(jìn)度落后的項(xiàng)目中增加人手,只會(huì)使進(jìn)度更加落后。”

“Adding mapower to a late software project makes it later.”

評(píng)論:注明的Brooks法則,人月神話一文的核心觀點(diǎn)。用人月這一觀念來衡量項(xiàng)目進(jìn)度帶有欺騙性。因?yàn)樗沟庙?xiàng)目看上去好像人力和時(shí)間是可交換的。如果時(shí)間不夠,那么增加人手就可以加快進(jìn)度。但是這個(gè)衡量方式忽略了新增加人手的培訓(xùn)時(shí)間、隊(duì)員之間的溝通時(shí)間等等因素,結(jié)果就是,盲目的增加人手只會(huì)導(dǎo)致項(xiàng)目落后。所以問題是,如何使得項(xiàng)目進(jìn)度不落后;要想使得項(xiàng)目進(jìn)度不落后,就要制定出合理的項(xiàng)目進(jìn)度。所以,問題是,如何制定出合理的項(xiàng)目進(jìn)度。

對于軟件任務(wù)的進(jìn)度安排,以下是我使用了很多年的經(jīng)驗(yàn)法則:

1/3 計(jì)劃

1/6 編碼

1/4 構(gòu)建測試和早期系統(tǒng)測試

1/4 系統(tǒng)測試,所有的構(gòu)建已完成

評(píng)論:充足的測試時(shí)間,只占1/6的編碼時(shí)間。可惜很多時(shí)候我們常常以為編碼時(shí)間就是全部的時(shí)間了,難怪會(huì)進(jìn)度落后。

外科手術(shù)隊(duì)伍

最好的和最差的表現(xiàn)在生產(chǎn)率上平均為10:1,在運(yùn)行速度和空間上具有5:1的驚人差異!簡言之,$20,000/年的程序員的生產(chǎn)率可能是¥10,000/年程序員的10倍。

得出的結(jié)論很簡單:如果一個(gè)200 人的項(xiàng)目中,有25 個(gè)最能干和最有開發(fā)經(jīng)驗(yàn)的項(xiàng)目經(jīng)理,那么開除剩下的175 名程序員,讓項(xiàng)目經(jīng)理來編程開發(fā)。

評(píng)論:所以說有經(jīng)驗(yàn)的程序員才是最廉價(jià)的勞動(dòng)力啊

Harlan Mills 的提議提供了一個(gè)嶄新的、創(chuàng)造性的解決方案2,3。Mills 建議大型項(xiàng)目的每一個(gè)部分由一個(gè)團(tuán)隊(duì)解決,但是該隊(duì)伍以類似外科手術(shù)的方式組建,而并非一擁而上。

也就是說,同每個(gè)成員截取問題某個(gè)部分的做法相反,由一個(gè)人來進(jìn)行問題的分解,其他人給予他所需要的支持,以提高效率和生產(chǎn)力。

評(píng)論:有時(shí)候民主和平等也許并非是最好的選擇:因?yàn)槭紫仍谌嗽谥橇ι稀⒛芰ι暇筒⒉黄降取M饪剖中g(shù)式的團(tuán)隊(duì)其實(shí)是延續(xù)了早期英雄式的編程風(fēng)格:主要的程序員決定了項(xiàng)目的大部分內(nèi)容,而其他人則成為他的副手,幫助他完成各項(xiàng)細(xì)節(jié)性的工作。

貴族專制、民主政治和系統(tǒng)設(shè)計(jì)

現(xiàn)在讓我們來處理具有濃厚感情色彩的問題——貴族統(tǒng)治和民主政治。結(jié)構(gòu)師難道不是新貴?他們一些智力精英,專門來告訴可憐的實(shí)現(xiàn)人員如何工作?是否所有的創(chuàng)造性活動(dòng)被那些精英單獨(dú)占有,實(shí)現(xiàn)人員僅僅是機(jī)器中的齒輪?難道不能遵循民主的理論,從所有的員工中搜集好的創(chuàng)意,以得到更好的產(chǎn)品,而不是將技術(shù)說明工作僅限定于少數(shù)人?

評(píng)論:為了實(shí)現(xiàn)概念完整性,在軟件體系結(jié)構(gòu)設(shè)計(jì)的時(shí)候必須實(shí)行貴族專制,讓少數(shù)的架構(gòu)師來決定整體的架構(gòu),普通程序員毫無發(fā)言權(quán)。但是Brooks為了安慰那些可憐的普通程序員,就告訴他們:其實(shí)實(shí)現(xiàn)細(xì)節(jié)也是需要一樣的創(chuàng)造性、同樣的新思路和卓越的才華。但是誰都知道,如果能夠成為貴族,為何要在制造工藝上費(fèi)勁心思呢?

畫蛇添足

第二個(gè)系統(tǒng)是設(shè)計(jì)師們所設(shè)計(jì)的最危險(xiǎn)的系統(tǒng)。而當(dāng)他著手第三個(gè)或第四個(gè)系統(tǒng)時(shí),先前的經(jīng)驗(yàn)會(huì)相互驗(yàn)證,得到此類系統(tǒng)通用特性的判斷,而且系統(tǒng)之間的差異會(huì)幫助他識(shí)別出經(jīng)驗(yàn)中不夠通用的部分。

一種普遍傾向是過分地設(shè)計(jì)第二個(gè)系統(tǒng),向系統(tǒng)添加很多修飾功能和想法,它們曾在第一個(gè)系統(tǒng)中被小心謹(jǐn)慎地推遲了。

評(píng)論:這個(gè)標(biāo)題起得讓人摸不清頭腦,其實(shí)值得是第二系統(tǒng)效應(yīng)(second-system effect)。認(rèn)識(shí)到第二個(gè)系統(tǒng)存在的風(fēng)險(xiǎn),可以讓架構(gòu)師保持警惕,少犯錯(cuò)誤。

為什么巴比倫塔會(huì)失敗?

  1. 清晰的目標(biāo)?是的,盡管幼稚得近乎不可能。而且,項(xiàng)目早在遇到這個(gè)基本的限制之前,就已經(jīng)失敗了。
  1. 人力?非常充足。
  1. 材料?在美索不達(dá)米亞有著豐富的泥土和柏油瀝青。
  1. 足夠的時(shí)間?沒有任何時(shí)間限制的跡象。
  1. 足夠的技術(shù)?是的,金字塔、錐形的結(jié)構(gòu)本身就是穩(wěn)定的,可以很好分散壓力負(fù)載。對磚石建筑技術(shù),人們有過深刻的研究。同樣,項(xiàng)目遠(yuǎn)在達(dá)到技術(shù)限制之間,就已經(jīng)失敗了。

那么,既然他們具備了所有的這些條件,為什么項(xiàng)目還會(huì)失敗呢?他們還缺乏些什么?兩個(gè)方面——交流,以及交流的結(jié)果——組織。他們無法相互交談,從而無法合作。當(dāng)合作無法進(jìn)行時(shí),工作陷入了停頓。通過史書的字里行間,我們推測交流的缺乏導(dǎo)致了爭辯、沮喪和群體猜忌。很快,部落開始分裂——大家選擇了孤立,而不是互相爭吵。

胸有成竹

本章只解決一個(gè)問題:一個(gè)程序員的生產(chǎn)效率究竟有多高?

對規(guī)模平均為3200指令的程序...大約單個(gè)的程序員所需要的編碼和調(diào)試時(shí)間為178個(gè)小時(shí),由此可以外推得到每年35800語句的生產(chǎn)率。而規(guī)模只有一半的程序花費(fèi)時(shí)間大約僅為前者的四分之一,相應(yīng)推斷出的生產(chǎn)率幾乎是每年80,000代碼行1。計(jì)劃、編制文檔、測試、系統(tǒng)集成和培訓(xùn)的時(shí)間必須被考慮在內(nèi)。因此,上述小型項(xiàng)目數(shù)據(jù)的外推是沒有意義的。就好像把100碼短跑記錄外推,得出人類可以在3分鐘之內(nèi)跑完1英里的結(jié)論一樣。

工作量和代碼行數(shù)不是線性關(guān)系,而是指數(shù)型關(guān)系:

工作量 = (常數(shù))×(指令的數(shù)量)^1.5

Aron的數(shù)據(jù):

很少的交互 10,000指令每人年

少量的交互 5,000

較多的交互 1,500

Harr的數(shù)據(jù)

OS/360的數(shù)據(jù)

600-800(經(jīng)過調(diào)試的指令)/人年

Corbato的數(shù)據(jù)

平均生產(chǎn)率是1200行經(jīng)過調(diào)試的PL/I語句/人年
Corbato的數(shù)據(jù)是行為單位,每行語句對應(yīng)3-5個(gè)指令。

上述所有數(shù)據(jù)的結(jié)論:

  1. 對于常用編程語句而言,生產(chǎn)率似乎是固定的。這個(gè)固定的生產(chǎn)率包括了編程中需要注釋,并可能存在錯(cuò)誤的情況。
  2. 生產(chǎn)率隨著系統(tǒng)復(fù)雜性或者難度增加而降低。
  3. 使用適當(dāng)?shù)母呒?jí)語言,編程的生產(chǎn)率可以提高5倍。

未雨綢繆

因此,管理上的問題不再是“是否構(gòu)建一個(gè)試驗(yàn)性的系統(tǒng),然后拋棄它?”你必須這樣做。現(xiàn)在的問題是“是否預(yù)先計(jì)劃拋棄原型的開發(fā),或者是否將該原型發(fā)布給用戶?”從這個(gè)角度看待問題,答案更加清晰。將原型發(fā)布給用戶,可以獲得時(shí)間,但是它的代價(jià)高昂——對于用戶,使用極度痛苦;對于重新開發(fā)的人員,分散了精力;對于產(chǎn)品,影響了聲譽(yù),即使最好的再設(shè)計(jì)也難以挽回名聲。

因此,為舍棄而計(jì)劃,無論如何,你一定要這樣做。

雖然Brooks在50年前就已經(jīng)提出構(gòu)建可拋棄原型的必要性,并且在各類開發(fā)模型中也都強(qiáng)調(diào)原型的必要性,但是到今天,可拋棄原型仍然沒有被大部分實(shí)踐所接受。或許,知道該做什么,和實(shí)際去做之間,永遠(yuǎn)存在一個(gè)鴻溝。另一種可能性是,可拋棄原型雖然很好,但是顯然沒有達(dá)到“必須”的程度。它帶來的好處不足以彌補(bǔ)其代價(jià),是今天大部分實(shí)踐中并未采用的原因。

系統(tǒng)軟件開發(fā)是減少混亂度(減少熵)的過程,所以它本身是處于亞穩(wěn)態(tài)的。軟件維護(hù)是提高混亂度(增加熵)的過程,即使是最熟練的軟件維護(hù)工作,也只是放緩了系統(tǒng)退化到非穩(wěn)態(tài)的進(jìn)程。

系統(tǒng)開發(fā)的熵論,非常的形象有趣。為變更而計(jì)劃組織架構(gòu),其實(shí)只是一句讓你認(rèn)識(shí)到軟件開發(fā)過程中“唯一不變的是變化”這一條真理。然而這也是一條悖論,如果只有變化的話,那么計(jì)劃就沒有意義了。關(guān)鍵在于我們需要計(jì)劃出不變的部分,為變化留出空間。

禍起蕭墻

項(xiàng)目是怎樣延遲了整整一年的時(shí)間?…一次一天。

但是一天一天的進(jìn)度落后是難以識(shí)別、不容易防范和難以彌補(bǔ)的。昨天,某個(gè)關(guān)鍵人員生病了,無法召開某個(gè)會(huì)議。今天,由于雷擊打壞了公司的供電變壓器,所有機(jī)器無法啟動(dòng)。明天,因?yàn)楣S磁盤供貨延遲了一周,磁盤例程的測試無法進(jìn)行。下雪、應(yīng)急任務(wù)、私人問題、同顧客的緊急會(huì)議、管理人員檢查——這個(gè)列表可以不斷地延長。每件事都只會(huì)將某項(xiàng)活動(dòng)延遲半天或者一天,但是整個(gè)進(jìn)度開始落后了,盡管每次只有一點(diǎn)點(diǎn)。

對于這種逐漸延遲的進(jìn)度,Brooks提議簡歷項(xiàng)目里程碑,并且持續(xù)的修訂項(xiàng)目計(jì)劃,這樣無論最后的情況變得多么糟糕,它都不會(huì)有太大的變化。里程碑是指百分之百的事件,必須有明顯的邊界和沒有歧義。這樣就很好有人可以在里程碑進(jìn)展上弄虛作假。

另外一面

需要文檔的必要性不言而喻,問題在于什么樣的文檔才是好的文檔。
本文中給出了以下文檔必要內(nèi)容的參考:

  1. 目的。主要的功能是什么?開發(fā)程序的原因是什么?
  2. 環(huán)境。程序運(yùn)行在什么樣的機(jī)器、硬件配置和操作系統(tǒng)上?
  3. 范圍。輸入的有效范圍是什么?允許顯示的合法范圍是什么?
  4. 實(shí)現(xiàn)功能和使用的算法。精確地闡述它做了什么。
  5. 輸入-輸出格式。必須是確切和完整的。
  6. 操作指令。包括控制臺(tái)及輸出內(nèi)容中正常和異常結(jié)束的行為。
  7. 選項(xiàng)。用戶的功能選項(xiàng)有哪些?如何在選項(xiàng)之間進(jìn)行挑選?
  8. 運(yùn)行時(shí)間。在指定的配置下,解決特定規(guī)模問題所需要的時(shí)間?
  9. 精度和校驗(yàn)。期望結(jié)果的精確程度?如何進(jìn)行精度的檢測?

沒有銀彈——軟件工程中的根本和次要問題

沒有任何技術(shù)或管理上的進(jìn)展,能夠獨(dú)立地許諾十年內(nèi)使生產(chǎn)率、可靠性或簡潔性獲得數(shù)量級(jí)上的進(jìn)步。

There is no single development, in either technology or management technique, which by itself promises even one order-of-magnitude improvement within a decade in productivity, in reliability, in simplicity.

軟件工程領(lǐng)域最著名的論斷。

所有軟件活動(dòng)包括根本任務(wù)——打造由抽象軟件實(shí)體構(gòu)成的復(fù)雜概念結(jié)構(gòu),次要任務(wù)——使用編程語言表達(dá)這些抽象實(shí)體,在空間和時(shí)間限制內(nèi)將它們映射成機(jī)器語言。

軟件工程領(lǐng)域的根本難題在于復(fù)雜度,一致性,可變性和不可見性。值得注意的是,文章末尾提出了一些可能的銀彈,比如面向?qū)ο缶幊蹋荒芙鉀Q軟件工程中的非本質(zhì)困難,而對于軟件工程根本的問題于事無補(bǔ)。就是說,我們某種程度上能夠解決使用編程語言表達(dá)抽象的實(shí)體,或者將其變得結(jié)構(gòu)化,構(gòu)建起完整的概念結(jié)構(gòu),但是仍然沒有解決軟件工程的根本難題——復(fù)雜度、一致性、可變性和不可見性。

因此,現(xiàn)在的技術(shù)中最有希望的,并且解決了軟件的根本而非次要問題的技術(shù),是開發(fā)作為迭代需求過程的一部分——快速原型化系統(tǒng)的方法和工具。

快速原型之所以可以解決根本問題,是因?yàn)榭焖僭陀兄诔吻遘浖こ痰母拍罱Y(jié)構(gòu),從而降低了后期變更的幅度。基于快速原型進(jìn)行增量開發(fā),目前已經(jīng)成為實(shí)際開發(fā)的標(biāo)準(zhǔn)流程。

再論《沒有銀彈》

Brooks在這篇文章里面再次討論了很多潛在的銀彈。因?yàn)樽詮摹稕]有銀彈》發(fā)表以后,遭到了大量的誤解、批評(píng)和質(zhì)疑,Brooks專門寫了這篇文章來繼續(xù)解釋他的觀點(diǎn)和回應(yīng)批評(píng)。

首先一個(gè)可能的銀彈是Harel提出的一種叫做Vanilla的框架,有助于程序的概念設(shè)計(jì)和圖形化呈現(xiàn),看上去確實(shí)直面軟件工程開發(fā)的根本困難:復(fù)雜性和不可見性。Brooks甚至也贊同如果Vanilla框架得到發(fā)展應(yīng)用,也許就是銀彈。但是今天看來,20年過去了似乎Vanilla已經(jīng)遭人遺忘。顯然它并非軟件開發(fā)的銀彈。

另一個(gè)可能的銀彈是定制軟件包的開發(fā)。基本上今天的開源社區(qū)已經(jīng)這樣做了。大量的公共庫被開發(fā)出來,確實(shí)提高了通用需求的開發(fā)效率。Brooks也承認(rèn),他低估了軟件包客戶化的程度和重要性。

面向?qū)ο缶幊蹋环Q為“銅制子彈”。但是面向?qū)ο蠹夹g(shù)“不會(huì)加快首次或第二次的開發(fā),產(chǎn)品族中第五個(gè)項(xiàng)目的開發(fā)才會(huì)異乎尋常的迅速”。不過經(jīng)過20年再來看,面向?qū)ο箅m然發(fā)展緩慢,但是的確已經(jīng)統(tǒng)治了軟件開發(fā)行業(yè),稱得上一顆“銅制子彈”。

軟件重用,也是一個(gè)可能的解決方案。

大多數(shù)有豐富經(jīng)驗(yàn)的程序員擁有自己的私人開發(fā)庫,可以使他們使用大約30%的重用代碼來開發(fā)軟件。公司級(jí)別的重用能提供70%的重用代碼量,它需要特殊的開發(fā)庫和管理支持。公司級(jí)別的重用代碼也意味著需要對項(xiàng)目中的變更進(jìn)行統(tǒng)計(jì)和度量,從而提高重用的可信程度。

但是重用面臨一個(gè)問題,就是重用所帶來的好處,必須大于其代價(jià),才得以實(shí)施。比如一個(gè)數(shù)學(xué)庫函數(shù),如果不重用,那么程序員自己需要學(xué)習(xí)大量的相關(guān)知識(shí)才能寫得出來。而對于項(xiàng)目中的某個(gè)功能,與其花費(fèi)很多功夫?qū)ふ抑赜玫哪K,可能程序員直接重新實(shí)現(xiàn)一次是更快捷的做法。

重用是一件說起來容易,做起來難的事情。它同時(shí)需要良好的設(shè)計(jì)和文檔。即使我們看到了并不十分常見的優(yōu)秀設(shè)計(jì),但如果沒有好的文檔,我們也不會(huì)看到能重用的構(gòu)件。

“不管怎樣,重用的模塊一般是一些通用功能。”

軟件重用的另一個(gè)問題是學(xué)習(xí)的成本。越復(fù)雜的功能,學(xué)習(xí)成本越高。高級(jí)語言比機(jī)器語言功能強(qiáng)大,但是也更加復(fù)雜。而重用一個(gè)模塊,則需要學(xué)習(xí)相應(yīng)該模塊的成本。這種成本今天已經(jīng)在各類專門開發(fā)職業(yè)中體現(xiàn)出來,如后臺(tái)程序員,Web前段或者手機(jī)客戶端,不同類別的程序員差別就在于其對某一重用模塊的專門知識(shí)的掌握。

20年后的人月神話

今天,我比以往更加確信。概念完整性是產(chǎn)品質(zhì)量的核心。擁有一位結(jié)構(gòu)式是邁向概念完整性的最重要一步。這個(gè)原理不僅限于軟件系統(tǒng),它適用于所有的復(fù)雜事物。

如果要我用一個(gè)詞語來概括人月神話,我想我會(huì)說“溝通代價(jià)”;如果可以有兩個(gè)詞,那就加上“概念完整性”。

20年后的人月神話有些結(jié)論得到驗(yàn)證,有些情況已經(jīng)變化,下面是這些情況的簡單概括:

  • 第二系統(tǒng)定律得到驗(yàn)證:開發(fā)第二個(gè)系統(tǒng)總是因?yàn)槊つ康墓δ軐?dǎo)致易用性、甚至是可用性的災(zāi)難。
  • 圖形界面的成功
  • 瀑布模型被證明是錯(cuò)的了,因?yàn)闆]有構(gòu)建舍棄原型。事實(shí)上增量開發(fā)與快速迭代才是理想的開發(fā)方式。
  • 增量開發(fā)和快速原型,漸進(jìn)地精華,讓軟件像生物進(jìn)化那樣逐漸演化成更為復(fù)雜的結(jié)構(gòu),演化出更多的功能。
  • 信息隱藏:Parnas是正確的,我是錯(cuò)誤的。20年前關(guān)于信息隱藏的兩大觀念,其一是Brooks主張的,所有的程序員應(yīng)該了解所有的材料。而Parnas則認(rèn)為代碼模塊應(yīng)該采用定義良好的接口來封裝,這些模塊內(nèi)部結(jié)構(gòu)應(yīng)該是程序員的私有財(cái)產(chǎn)。Brooks承認(rèn),Parnas所主張的方案確實(shí)更符合實(shí)際。
  • 對人月神話實(shí)際研究發(fā)現(xiàn),向進(jìn)度落后的項(xiàng)目中添加人手會(huì)增加項(xiàng)目的成本,但是不一定會(huì)使項(xiàng)目更加落后。如果在項(xiàng)目早期添加額外的人比在后期添加額外的人更安全些。
  • 人就是一切。這一點(diǎn)可以從《人件:高生產(chǎn)率的項(xiàng)目和團(tuán)隊(duì)》可以見出。
  • 放棄權(quán)利的力量——公司通過將權(quán)利下放到具體的團(tuán)隊(duì),事實(shí)上使得組織機(jī)構(gòu)變得更加“融洽和繁榮”。
  • 最令人驚訝的新事物——數(shù)百萬的計(jì)算機(jī)
  • 使用塑料包裝的成品軟件包作為構(gòu)建:成熟的模塊和對象組合提升了軟件復(fù)用的層次。

軟件工程的未來

軟件工程的焦油坑在將來很長一段時(shí)間內(nèi)會(huì)繼續(xù)地使人們舉步維艱,無法自拔。軟件系統(tǒng)可能是人類創(chuàng)造中最錯(cuò)綜復(fù)雜的事物,只能期待人們在力所能及的或者剛剛超越力所能及的范圍內(nèi)進(jìn)行探索和嘗試。這個(gè)復(fù)雜的行業(yè)需要:進(jìn)行持續(xù)的發(fā)展;學(xué)習(xí)使用更大的要素來開發(fā);新工具的最佳使用;經(jīng)論證的管理方法的最佳應(yīng)用;良好判斷的自由發(fā)揮;以及能夠使我們認(rèn)識(shí)到自己不足和容易犯錯(cuò)的——上帝所賜予的謙卑。

參考

《人月神話》FREDERICK P. BROOKS, JR.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容