1 焦油坑:
1.大型軟件系統(tǒng)開(kāi)發(fā)就像史前各種巨獸在焦油坑中垂死掙扎的場(chǎng)景。在眾多的大型項(xiàng)目開(kāi)發(fā)中,大多數(shù)能夠開(kāi)發(fā)出可運(yùn)行的系統(tǒng),但是其中只有非常少數(shù)的項(xiàng)目滿足了目標(biāo),時(shí)間進(jìn)度和預(yù)算的需求。各種團(tuán)隊(duì),大型的和小型的,龐雜的和精干的,一個(gè)接著一個(gè)淹沒(méi)在了焦油坑中。表面上看起來(lái)沒(méi)有任何一個(gè)單獨(dú)的問(wèn)題會(huì)導(dǎo)致困難,每個(gè)都能被獨(dú)立解決,但是當(dāng)他們相互糾纏和積累在一起的時(shí)候,團(tuán)隊(duì)和行動(dòng)就會(huì)變得越來(lái)越慢。
2 .編程系統(tǒng)產(chǎn)品:程序和編程系統(tǒng)、編程產(chǎn)品、編程系統(tǒng)產(chǎn)品是截然不同的概念,最終的編程系統(tǒng)的開(kāi)發(fā)成本大概是最初實(shí)現(xiàn)單元功能程序的九倍左右。
3.編程為什么有趣?作為回報(bào),它的從業(yè)者期望得到什么樣的快樂(lè)?
首先是一種創(chuàng)建事物的純粹快樂(lè)。其次,快樂(lè)來(lái)自于開(kāi)發(fā)對(duì)其他人有用的東西。第三是整個(gè)過(guò)程體現(xiàn)出魔術(shù)般的力量--將相互嚙合的零部件組裝在一起,看到它們精妙地運(yùn)行,得到預(yù)先所希望的結(jié)果。比起彈珠游戲或點(diǎn)唱機(jī)所具有的迷人魅力,程序化的計(jì)算機(jī)毫不遜色。第四是學(xué)習(xí)的樂(lè)趣,來(lái)自于這項(xiàng)工作的非重復(fù)特性。編程非常有趣,在于它不僅滿足了我們內(nèi)心深處進(jìn)行創(chuàng)造的渴望,而且還愉悅了每個(gè)人內(nèi)在的情感。
2 人月神話
所有的編程人員都是樂(lè)觀主義者。我們?cè)诠浪沩?xiàng)目進(jìn)度的時(shí)候,容易隱含地假設(shè)人和月可以互換,從而錯(cuò)誤地將進(jìn)度和工作量相互混淆。然而人數(shù)和時(shí)間的護(hù)花僅僅適用于任務(wù)可以分解給獨(dú)立地參與人員,并且這些參與人員不會(huì)進(jìn)行任何交流的情況下。這在系統(tǒng)編程中近乎不可能。事實(shí)上,編程屆有一個(gè)著名的Brooks法則:向進(jìn)度落后的項(xiàng)目中增加人手,只會(huì)使得該項(xiàng)目的進(jìn)度更加落后。在眾多的軟件項(xiàng)目中,缺乏合理的時(shí)間進(jìn)度安排是造成項(xiàng)目進(jìn)度落后的最主要原因。
3 外科手術(shù)隊(duì)伍
優(yōu)秀程序員和較差的程序員之間的差異非常巨大。絕大多數(shù)系統(tǒng)編程的經(jīng)驗(yàn)指出,一擁而上的開(kāi)發(fā)方法是高成本的,速度緩慢的,不充分的。開(kāi)發(fā)出的是無(wú)法在概念上進(jìn)行集成的產(chǎn)品。Harlan Mills建議大型項(xiàng)目的每一個(gè)部分由一個(gè)團(tuán)隊(duì)去解決,但是隊(duì)伍的形式是以類似外科手術(shù)的方式組建,由一個(gè)人進(jìn)行問(wèn)題的分解,其他人給與他所需要的支持,以提高效率和生產(chǎn)力。這里外科醫(yī)生就是首席程序員,他負(fù)責(zé)統(tǒng)籌需求,任務(wù)分解,架構(gòu)設(shè)計(jì)和進(jìn)度安排。其中需要有一個(gè)副手,也就是外科醫(yī)生的后備,他在軟件開(kāi)發(fā)小組里面擔(dān)任思考著和建議者,首席程序員會(huì)跟他進(jìn)行溝通設(shè)計(jì),但是不受他建議的限制。同時(shí),外科手術(shù)團(tuán)隊(duì)中有一個(gè)管理員的角色,負(fù)責(zé)控制財(cái)務(wù),人員,工作時(shí)間地點(diǎn)安排和機(jī)器的管理等責(zé)任。在軟件開(kāi)發(fā)中,一個(gè)管理員的角色可以為不止一個(gè)開(kāi)發(fā)團(tuán)隊(duì)進(jìn)行服務(wù)。此外,團(tuán)隊(duì)中還應(yīng)該有編輯,程序職員等角色。程序員的專業(yè)化分工,使他們從書(shū)記的雜事中解放出來(lái)。外科手術(shù)式的團(tuán)隊(duì)人員分工如圖所示:
4 貴族專制、民主政治和系統(tǒng)設(shè)計(jì)
在軟件系統(tǒng)的設(shè)計(jì)中,概念完整性是最重要的考慮因素。為了反映一系列連貫的設(shè)計(jì)思路,寧可省略一些不規(guī)則的特性和改進(jìn),也不提倡獨(dú)立和無(wú)法整合的系統(tǒng),哪怕他它其實(shí)包含著許多很好的設(shè)計(jì)。
對(duì)于小型的項(xiàng)目,可以按照上一章中說(shuō)的“外科手術(shù)隊(duì)伍”的模式來(lái)組建開(kāi)發(fā)團(tuán)隊(duì),這樣完全可以保證系統(tǒng)概念的完整性。
對(duì)于大型的項(xiàng)目,為了概念的完整性,最強(qiáng)有力的方法就是將設(shè)計(jì)與具體實(shí)現(xiàn)分離。設(shè)計(jì)由一個(gè)人或者極少數(shù)人來(lái)完成,具體實(shí)現(xiàn)交給人數(shù)較多的實(shí)現(xiàn)人員來(lái)完成。設(shè)計(jì)人員對(duì)整個(gè)系統(tǒng)的設(shè)計(jì)具有專制的權(quán)利,可以保留其他人員對(duì)設(shè)計(jì)提建議的權(quán)利,但建議是否采用完全取決于設(shè)計(jì)人員,一切都以不破壞系統(tǒng)概念的完整性為準(zhǔn)則。
這樣并未剝奪具體實(shí)現(xiàn)人員的創(chuàng)造性,因?yàn)樵谠O(shè)計(jì)好的體系結(jié)構(gòu)下進(jìn)行實(shí)現(xiàn),同樣需要?jiǎng)?chuàng)造性、需要新的思路和卓越的才華。 同傳統(tǒng)上將工作進(jìn)行水平分割相比,垂直劃分從根本上大大減少了勞動(dòng)量,結(jié)果是使交流徹底地簡(jiǎn)化,概念完整性得到大幅度提高。
5 畫(huà)蛇添足
盡早交流和持續(xù)溝通能使結(jié)構(gòu)師有較好的成本意識(shí),以及使開(kāi)發(fā)人員獲得對(duì)設(shè)計(jì)的信心,并且不會(huì)混淆各自的責(zé)任分工。
結(jié)構(gòu)師如何成功地影響實(shí)現(xiàn): 牢記是開(kāi)發(fā)人員承擔(dān)創(chuàng)造性的實(shí)現(xiàn)責(zé)任;結(jié)構(gòu)師只能提出建議。聽(tīng)取開(kāi)發(fā)人員在體系結(jié)構(gòu)上改進(jìn)的建議。
第二個(gè)系統(tǒng)是人們所設(shè)計(jì)的最危險(xiǎn)的系統(tǒng),通常的傾向是過(guò)分地進(jìn)行設(shè)計(jì)。關(guān)于這一點(diǎn)也許是正確的,但是這是一個(gè)回避不了的問(wèn)題,如果沒(méi)有開(kāi)發(fā)第二個(gè)系統(tǒng)經(jīng)驗(yàn)的人,就不可能有開(kāi)發(fā)第三個(gè)系統(tǒng)經(jīng)驗(yàn)的人了。
6 貫徹執(zhí)行
即使是大型的設(shè)計(jì)團(tuán)隊(duì),設(shè)計(jì)結(jié)果也必須由一個(gè)或兩個(gè)人來(lái)完成,以確保這些決定是一致的。
必須明確定義體系結(jié)構(gòu)中與先前定義不同的地方,重新定義的詳細(xì)程度應(yīng)該與原先的說(shuō)明一致。
出于精確性的考慮,我們需要形式化的設(shè)計(jì)定義,同樣,我們需要記敘性定義來(lái)加深理解。
允許體系結(jié)構(gòu)師對(duì)實(shí)現(xiàn)人員的詢問(wèn)做出電話應(yīng)答解釋是非常重要的,并且必須進(jìn)行日志記錄和整理發(fā)布。
項(xiàng)目經(jīng)理最好的朋友就是他每天要面對(duì)的敵人——獨(dú)立的產(chǎn)品測(cè)試機(jī)構(gòu)/小組。
7 為什么巴比倫塔會(huì)失敗?
巴比倫塔項(xiàng)目的失敗是因?yàn)槿狈涣鳎约敖涣鞯慕Y(jié)果的組織。
因?yàn)樽笫植恢烙沂衷谧鍪裁矗瑥亩M(jìn)度災(zāi)難、功能的不合理和系統(tǒng)缺陷紛紛出現(xiàn)。由于對(duì)其他人的各種假設(shè),團(tuán)隊(duì)成員之間的理解開(kāi)始出現(xiàn)偏差。
團(tuán)隊(duì)?wèi)?yīng)該以盡可能多的方式進(jìn)行相互之間的交流:非正式、常規(guī)項(xiàng)目會(huì)議,會(huì)上進(jìn)行簡(jiǎn)要的技術(shù)陳述、共享的正式項(xiàng)目工作手冊(cè)。
8 胸有成竹
僅僅通過(guò)對(duì)編碼部分的估計(jì),然后乘以任務(wù)其他部分的相對(duì)系數(shù),是無(wú)法得出對(duì)整項(xiàng)工作的精確估計(jì)的。
構(gòu)建獨(dú)立小型程序的數(shù)據(jù)不適用于編程系統(tǒng)項(xiàng)目。
程序開(kāi)發(fā)與程序規(guī)模成指數(shù)增長(zhǎng)趨勢(shì)。
當(dāng)使用適當(dāng)?shù)母呒?jí)語(yǔ)言時(shí),程序編制的生產(chǎn)率可以提高5倍。
9 削足適履
要解決項(xiàng)目投資與磁盤空間和內(nèi)存之間的矛盾,但是這個(gè)矛盾在電腦硬件發(fā)展到現(xiàn)在的層次已經(jīng)可以忽略掉了。
軟件項(xiàng)目的要求:目標(biāo)、用戶手冊(cè)、內(nèi)部文檔、進(jìn)度、預(yù)算、組織機(jī)構(gòu)圖和工作空間分配。
即使是小型項(xiàng)目,項(xiàng)目經(jīng)理也應(yīng)該在項(xiàng)目早期規(guī)范化上述的一系列文檔。
這一章強(qiáng)調(diào)文檔重要性,但并沒(méi)有將一些教條主義的道理讓你相信文檔的重要性,而是給項(xiàng)目經(jīng)理給出了實(shí)實(shí)在在的操作步驟。
10 未雨綢繆
對(duì)于大多數(shù)項(xiàng)目,第一個(gè)開(kāi)發(fā)的系統(tǒng)并不合用。它可能太慢、太大,而且難以使用,或者三者兼而有之。系統(tǒng)的丟棄和重新設(shè)計(jì)可以一步完成,也可以一塊塊地實(shí)現(xiàn)。這是個(gè)必須完成的步驟,如果將開(kāi)發(fā)的第一個(gè)系統(tǒng)丟棄原型發(fā)布給用戶,可以獲得時(shí)間,但是它的代價(jià)很高。對(duì)于用戶,使用極度痛苦;對(duì)于重新開(kāi)發(fā)的人員,分散了精力;對(duì)于產(chǎn)品,影響了聲譽(yù),即使最好的再設(shè)計(jì)也難以挽回名聲。
用戶的實(shí)際需要和用戶感覺(jué)會(huì)隨著程序的構(gòu)建、測(cè)試和使用而變化。
軟件產(chǎn)品易于掌握的特性和不可見(jiàn)性,導(dǎo)致了它的構(gòu)建人員面臨著永恒的需求變更。
目標(biāo)和開(kāi)發(fā)策略上的一些正常變化無(wú)可避免,事先為它們做準(zhǔn)備總比假設(shè)它們不會(huì)出現(xiàn)要好得多。對(duì)于一個(gè)廣泛使用的程序,其維護(hù)總成本通常是開(kāi)發(fā)成本的40%或更多。
維護(hù)成本受用戶數(shù)目的嚴(yán)重影響。用戶越多,所發(fā)現(xiàn)的錯(cuò)誤也越多。
缺陷修復(fù)總會(huì)以(20-50)%的機(jī)率引入新的bug。在每次修復(fù)之后,必須重新運(yùn)行先前所有的測(cè)試用例,從而確保系統(tǒng)不會(huì)以更隱蔽的方式被破壞。設(shè)計(jì)實(shí)現(xiàn)的人員越少、接口越少,產(chǎn)生的錯(cuò)誤也就越少。
所有修改都傾向于破壞系統(tǒng)的架構(gòu),增加了系統(tǒng)的混亂程度。即使是最熟練的軟件維護(hù)工作,也只是放緩了系統(tǒng)退化到不可修復(fù)混亂的進(jìn)程。
11 干將莫邪
項(xiàng)目經(jīng)理應(yīng)該制訂一套策略,以及為通用工具的開(kāi)發(fā)分配資源,與此同時(shí),他還必須意識(shí)到專業(yè)工具的需求。
12 禍起蕭墻
一天一天的進(jìn)度落后比起重大災(zāi)難,更難以識(shí)別,更不容易防范和更加難以彌補(bǔ)。
根據(jù)一個(gè)嚴(yán)格的進(jìn)度表來(lái)控制項(xiàng)目的第一個(gè)步驟是制訂進(jìn)度表,進(jìn)度表由里程碑和日期組成。
里程碑必須是具體的、特定的、可度量的事件,能進(jìn)行清晰能定義。
如果里程碑定義得非常明確,以致于無(wú)法自欺欺人時(shí),程序員很少會(huì)就里程碑的進(jìn)展弄虛作假。
13 另外一面
對(duì)于軟件編程產(chǎn)品來(lái)說(shuō),程序向用戶所呈現(xiàn)的面貌與提供給機(jī)器識(shí)別的內(nèi)容同樣重要。
即使對(duì)于完全開(kāi)發(fā)給自己使用的程序,描述性文字也是必須的,因?yàn)樗鼈儠?huì)被用戶和作者所遺忘。
文檔能在整個(gè)軟件開(kāi)發(fā)的生命周期對(duì)程序員克服懶惰和進(jìn)度的壓力起促進(jìn)激勵(lì)作用,但向編程人員成功地灌輸對(duì)待文檔的積極態(tài)度是一件困難的事情。
為了使文檔易于維護(hù),將它們合并至源程序是至關(guān)重要的,而不是作為獨(dú)立文檔進(jìn)行保存。
14 沒(méi)有銀彈
人狼的傳說(shuō)可能有人聽(tīng)過(guò)也可能沒(méi)聽(tīng)過(guò),人狼是一種具有人和狼兩種特征的恐怖生物,而銀彈是消滅它的一種最有效的子彈,如果看過(guò)《吸血鬼傳說(shuō)》也許就能和容易的理解這一點(diǎn)。作者將軟件開(kāi)發(fā)比作人狼,而將提高軟件開(kāi)發(fā)效率的方法比作銀彈。作者預(yù)言未來(lái)十年,想要試圖通過(guò)尋找一種有效地銀彈將軟件開(kāi)發(fā)效率提高一個(gè)甚至幾個(gè)數(shù)量級(jí),這種銀彈不可能出現(xiàn)。
軟件工程的焦油坑在將來(lái)很長(zhǎng)一段時(shí)間內(nèi)會(huì)繼續(xù)困擾著人們。由于軟件系統(tǒng)多變性和錯(cuò)綜復(fù)雜性,這個(gè)行業(yè)只能是一步一個(gè)臺(tái)階的往上爬,而出現(xiàn)銀彈的希望在我們可以想象的時(shí)間范圍內(nèi)是非常渺茫的。我們將長(zhǎng)期與焦油作斗爭(zhēng)。