- 敏捷開發(fā)(紀(jì)念版)
- (美)羅伯特·C.馬丁等
- 5359字
- 2023-08-31 19:23:29
前言

“可是老兄,你說你去年就會完成這本書的?!本嚯x1999年Claudia發(fā)出這一正當(dāng)?shù)谋г梗呀?jīng)過去7年了,但我(Bob)(1)覺得已經(jīng)做出了補(bǔ)償。我要經(jīng)營一家咨詢公司,做大量編碼、培訓(xùn)、輔導(dǎo)和演講工作,寫文章、專欄和博客,更不用提還要養(yǎng)家糊口并享受大家庭的樂趣。所以,這期間寫三本書(每兩年一本)真的是一個巨大的挑戰(zhàn)。但是,我樂在其中。
敏捷開發(fā)是在需求快速變化的情況下快速開發(fā)軟件的一種能力。為實(shí)現(xiàn)這種敏捷性,需使用能提供必要紀(jì)律和反饋的實(shí)踐,需遵守保持軟件靈活且易于維護(hù)的設(shè)計(jì)原則,需知道已證明能為特定問題權(quán)衡那些原則的設(shè)計(jì)模式。本書旨在將這三個概念整合成一個有機(jī)的整體。
本書介紹了這些原則、模式與實(shí)踐,然后通過多個案例來演示其實(shí)際運(yùn)用。更重要的是,這些案例都不是“成品”。相反,它們是進(jìn)行中的設(shè)計(jì)。你會看到設(shè)計(jì)人員犯錯,觀察到他們?nèi)绾伟l(fā)現(xiàn)并最終糾正錯誤,會看到設(shè)計(jì)人員對一個難題苦思不得其解,并擔(dān)心歧義和得失??傊憧吹降氖窃O(shè)計(jì)實(shí)際在進(jìn)行。
2005年初,我(Micah)在一個小開發(fā)團(tuán)隊(duì)做事,當(dāng)時(shí)要著手用C#來寫一個.NET應(yīng)用程序。項(xiàng)目要求采用敏捷開發(fā)實(shí)踐,這正是我進(jìn)入該項(xiàng)目的原因之一。雖然以前用過C#,但我最熟悉的還是Java和C++。
當(dāng)時(shí)沒想過用.NET會有多大區(qū)別,事實(shí)證明確實(shí)如此。項(xiàng)目進(jìn)行了兩個月,我們發(fā)布了第一個版本。不是完整版本,只包含所有預(yù)期功能的一部分,但足夠用。他們也真的在用。僅過了兩個月,公司就從我們的開發(fā)收獲了好處。管理層高興,嚷著要雇更多人,啟動更多項(xiàng)目。
多年來一直出沒于敏捷社區(qū),我知道有許多敏捷開發(fā)人員能幫到我們。我給他們打了電話,請他們加入。最終,沒有任何一個搞敏捷的人加入我們的團(tuán)隊(duì)。為什么?或許最重要的原因是我們用的是.NET。
幾乎所有敏捷開發(fā)人員都有Java,C++或Smalltalk的背景。但幾乎沒聽說過有敏捷.NET程序員。我說要用.NET進(jìn)行敏捷軟件開發(fā),我的那些朋友可能根本沒有把我的話當(dāng)真,或者他們就是不想和.NET扯上關(guān)系。這是一個大問題。而且,發(fā)生過好多次。
為期一周的有關(guān)各種軟件主題的課程使我能結(jié)識來自世界各地的開發(fā)人員。
就各種軟件主題講授大約一周的課程,使我有機(jī)會接觸來自世界各地有代表性的開發(fā)人員。許多學(xué)員都是.NET程序員,也有許多是Java或C++程序員。雖然不好聽,但根據(jù)我的經(jīng)驗(yàn),.NET程序員通常比Java和C ++程序員要弱一些。顯然,并非總是如此。但通過在課堂上反復(fù)觀察,我只能得出這樣的結(jié)論:.NET程序員在敏捷軟件實(shí)踐、設(shè)計(jì)模式和設(shè)計(jì)原則等方面通常要弱一些。據(jù)我觀察,許多.NET程序員從未聽說過這些基本概念。這種情況必須改變!
我父親Robert C. Martin于2002年出版了的《敏捷軟件開發(fā):原則、模式與實(shí)現(xiàn)》榮獲了2003年Jolt大獎。那是本好書,受到許多開發(fā)人員的推崇。遺憾的是,它對.NET社區(qū)影響甚微。雖然書的內(nèi)容同樣適合.NET,但鮮有.NET程序員讀過。
我希望講.NET的這一版能在.NET和開發(fā)社區(qū)其余部分之間建立起一座橋梁。希望程序員能讀一讀,了解構(gòu)建軟件的更優(yōu)方式。希望他們開始使用更好的軟件實(shí)踐,創(chuàng)建更好的設(shè)計(jì),提升.NET應(yīng)用程序員的質(zhì)量標(biāo)準(zhǔn)。希望.NET程序員不再比其他程序員弱。希望.NET程序員在軟件社區(qū)取得更多話語權(quán),就連Java開發(fā)人員也樂意加入一個.NET團(tuán)隊(duì)。
寫書的過程中,我經(jīng)常糾結(jié)于要不要把我的名字放在一本.NET書的封面。這樣會不會將我和.NET聯(lián)系起來,會不會有不好的暗示?但最終我不再糾結(jié)。我是一名.NET程序員。不對!一名敏捷.NET程序員!我為此感到驕傲。
關(guān)于本書
20世紀(jì)90年代初,我(Bob)寫了Designing Object-Oriented C++ Applications Using the Booch Method一書,是我的代表作,我對其影響和銷量都很滿意。其實(shí)你現(xiàn)在正在看的最開始就是想作為那本書的第3版,只是后來完全不是那么回事。原作內(nèi)容在本書所剩無己,不超過3章,而且都進(jìn)行了大幅修訂。書的意圖、精神和許多啟發(fā)并沒有改變。在該書問世后的十年里,我在軟件設(shè)計(jì)和開發(fā)方面學(xué)到了很多。本書反映了我學(xué)到的東西。
這是怎樣的十年??!該書是在互聯(lián)網(wǎng)時(shí)代之前出版的?;ヂ?lián)網(wǎng)問世后,需要掌握的縮寫詞數(shù)量大增。我們現(xiàn)在有了EJB、RMI、J2EE、XML、XSLT、HTML、ASP、JSP、ZOPE、SOAP、C#和.NET,另外還有設(shè)計(jì)模式、Java、Servelets和Application Servers?;旧希贡緯姓鹿?jié)的內(nèi)容保持“最新”是很難的。
本書和Booch的關(guān)系
1997年,Grady Booch(2)邀請我?guī)兔懰潜敬螳@成功的Object-Oriented Analysis and Design with Applications一書的第3版。我以前和Grady在一些項(xiàng)目上合作過,是其許多作品(包括UML)的熱心讀者和內(nèi)容貢獻(xiàn)者。所以,我高興地接受了邀請,并請我的好友Jim Newkirk共同參與。
接下來的兩年,我和Jim為Booch寫了許多章節(jié),花在本書上的精力自然就少了。但是,我覺得Booch的書值得投入。另外,當(dāng)時(shí)還在想本書反正只是第2版,所以并不是特別上心。如果我要寫一些有份量的內(nèi)容,我會寫一些新的、不一樣的。
遺憾的是,Booch的書難產(chǎn)了。本來就很難在正常時(shí)間寫書,在互聯(lián)網(wǎng)泡沫的那段時(shí)間更是不太可能。Grady在Rational Software的工作更忙了,同時(shí)還忙于像Catapulse這樣的風(fēng)投企業(yè)。所以,項(xiàng)目陷入停頓。最終,我問Grady和Addison-Wesley出版社能不能把我和Jim寫的章節(jié)放到本書。他們慷慨地同意了。本書的幾個案例分析和UML章節(jié)就是這么來的。
極限編程的影響
1998年末,極限編程(XP)嶄露頭角,挑戰(zhàn)我們對于軟件開發(fā)的傳統(tǒng)觀念。是應(yīng)該在寫任何代碼之前創(chuàng)建大量UML圖,還是避免一切形式的圖,直接寫大量代碼?是應(yīng)該寫許多說明性的文檔來描述設(shè)計(jì),還是使代碼更具說明性,從而無需輔助文檔?要結(jié)對寫程序嗎?寫生產(chǎn)代碼前要先寫好測試代碼嗎?我們到底應(yīng)該怎么做?
這個變革來得恰是時(shí)候。20世紀(jì)90年代中期,Object Mentor幫助許多公司解決OO(面向?qū)ο螅┰O(shè)計(jì)和項(xiàng)目管理問題。我們幫這些公司完成其項(xiàng)目。在這個過程中,我們向團(tuán)隊(duì)灌輸了自己的態(tài)度與實(shí)踐。遺憾的是,這些東西沒有形成書面記錄。相反,只是從口頭上傳達(dá)給了客戶。
1998年,我意識到需要把我們的過程和實(shí)踐記錄下來,以便更好地向客戶傳達(dá)。所以我在C++ Report上寫了許多關(guān)于這一過程的文章(3)。但是,這些文章沒有達(dá)到目標(biāo)。信息量大,有時(shí)還十分有趣,但它們沒有將我們在項(xiàng)目中采用的實(shí)踐和態(tài)度整理成文,面是對數(shù)十年來我形成的價(jià)值觀的一種無意識的折衷。最后是Kent Beck提醒了我。
本書和Kent的關(guān)系
1998年末,正當(dāng)我為Object Mentor過程的整理而煩惱時(shí),Kent和Beck在極限編程(XP)方面的成果讓我眼前一亮。這些成果散見于Ward Cunningham(4)的wiki(5),和其他許多人的作品混在一起。盡管如此,作為一個有心人,我還是掌握了Kent的要點(diǎn)。感興趣的同時(shí),我也有了一些疑慮。極限編程的某些東西契合我的開發(fā)過程目標(biāo)。但另一些東西,比如缺乏一個明確的設(shè)計(jì)階段,卻讓我疑惑。
我和Kent處于截然不同的軟件環(huán)境。他是公認(rèn)的Smalltalk顧問,我是公認(rèn)的C++顧問。這兩個世界相互很難溝通,存在像庫恩范式(6)那么大的鴻溝。
其他時(shí)候我絕不會邀請Kent為C++ Report撰稿。但是,由于我們對于過程的看法取得了一致,所以語言的鴻溝不再重要。1999年2月,我在慕尼黑的OOP大會上見到了Kent。我當(dāng)時(shí)在講OOD的原則,他就在對面的房間里講XP。由于沒法聽到他的演講,我在午餐時(shí)找到了Kent。我們討論了XP,我提出了讓他為C++ Report撰稿的請求。這是一篇很棒的文章,討論了Kent如何和一名同事花一小時(shí)左右的時(shí)間在某個live system中進(jìn)行一次全面的設(shè)計(jì)更改。
接著幾個月,我慢慢梳理出了自己對XP的憂慮。最擔(dān)心的是如何采納一個沒有明顯前期設(shè)計(jì)階段的過程。感覺自己好像卡在了這里。對于我的客戶及其整個行業(yè),我難道不應(yīng)該告訴他們值得花時(shí)間在設(shè)計(jì)上嗎?
最后,我終于意識到自己都沒有真正注重過這樣的一個階段。即使在我寫的關(guān)于設(shè)計(jì)、Booch圖和UML圖的所有文章和書里,都總是將代碼作為驗(yàn)證圖是否有意義的一種方式來使用。在我的所有客戶咨詢中,我會花一兩個小時(shí)幫客戶畫圖,再指導(dǎo)他們通過代碼來利用這些圖。我意識到雖然XP關(guān)于設(shè)計(jì)的說法有點(diǎn)陌生,有點(diǎn)庫恩(7),但其背后的實(shí)踐我本來就熟悉。
我對XP的其他擔(dān)心較容易解決。我私底下一直擁護(hù)結(jié)對編程。XP使我能光明正大地和伙伴一起編程。重構(gòu)、持續(xù)集成、在客戶現(xiàn)場工作……所有這些對我來說都很容易接受。它們很接近我向客戶建議的工作方式。
XP的一個實(shí)踐對我來說是新的發(fā)現(xiàn)。第一次聽說“測試驅(qū)動開發(fā)”(Test-driven development,TDD)(8)時(shí)可能感覺沒什么:寫生產(chǎn)代碼前先寫好測試用例,寫所有生產(chǎn)代碼的目的都是使失敗的測試用例通過測試。但是,我對這種開發(fā)模式所帶來的深遠(yuǎn)影響始料未及。該實(shí)踐徹底改變了我寫軟件的方式:變得更好了。
所以,1999年秋,我確信Object Mentor應(yīng)采納XP作為其選擇的過程,并且我應(yīng)該放棄寫自己的過程的想法。Kent已經(jīng)很好地歸納了XP的實(shí)踐與過程,我的小小嘗試與之相比不值一提。
.NET
各大企業(yè)正在進(jìn)行一場戰(zhàn)爭,目的是爭取你的效忠。它們認(rèn)為,只要擁有了語言,就擁有了程序員以及雇用這些程序員的公司。
這場戰(zhàn)爭的第一個爭奪點(diǎn)是Java。Java是第一個由大公司為贏得程序員關(guān)注而創(chuàng)建的語言,并取得了極大成功。Java在軟件社區(qū)深得人心,基本上是現(xiàn)代多層IT應(yīng)用程序的事實(shí)上的標(biāo)準(zhǔn)。
相應(yīng)的一個還擊來自IBM,它通過Eclipse開發(fā)環(huán)境奪走了很大一塊Java市場。Microsoft技術(shù)精湛的開發(fā)人員也不甘落后,他們提供了常規(guī)意義上的.NET和最為特殊的C#。
令人驚訝的是,Java和C#很難區(qū)分。兩種語言語義一致,語法也相似,以至于許多代碼段沒有差別。雖然Microsoft在技術(shù)創(chuàng)新上差點(diǎn)意思,但它趕超別人并取得最終勝利的能力還是相當(dāng)不錯的。
本書第一版采用Java和C++作為編碼語言。本書則完全采用C#和.NET平臺。不要把這當(dāng)成是背書。這場戰(zhàn)爭我們不選邊站。事實(shí)上,大公司為爭奪程序員的關(guān)注而發(fā)起的戰(zhàn)爭沒有太大意義。未來幾年一旦出現(xiàn)更好的語言,程序員的心思立即就會發(fā)生轉(zhuǎn)移。
本書之所以出.NET版,自然是為了方便.NET讀者。雖然書中的原則、模式與實(shí)踐和語言無關(guān),但案例分析不是。.NET程序員看.NET的案例分析更舒服,Java程序員看Java的例子更愉快。
魔鬼就在細(xì)節(jié)里

本書包含大量.NET代碼。希望你能仔細(xì)讀代碼,因?yàn)榇a在很大程度上就是本書的重點(diǎn)。代碼具現(xiàn)了本書要表達(dá)的意思。
本書采用固定寫作模式:大小不一的一系列案例分析。有的非常小,有的則需要用幾章來講解。每個案例分析都有一些前置材料,描述了該案例分析要用到的面向?qū)ο笤O(shè)計(jì)原則和模式。
本書首先討論開發(fā)實(shí)踐和過程,其中穿插了許多小的案例分析和例子。然后開始討論設(shè)計(jì)和設(shè)計(jì)原則,接著討論一些設(shè)計(jì)模式,對包進(jìn)行管控的更多設(shè)計(jì)原則,以及更多模式。所有這些主題都伴隨有相應(yīng)的案例分析。
所以,要做好讀一些代碼和研究一些UML圖的準(zhǔn)備。本書技術(shù)性很強(qiáng),它要傳授的經(jīng)驗(yàn)教訓(xùn)如同惡魔一樣隱藏在細(xì)節(jié)里(細(xì)節(jié)決定成?。?。
本書的結(jié)構(gòu)
本書包含4部分38章和2個附錄。
第Ⅰ部分:敏捷開發(fā)。本部分描述敏捷開發(fā)的概念。首先展示敏捷聯(lián)盟宣言,概述了極限編程(XP),然后通過許多小的案例分析來闡述一些單獨(dú)的XP實(shí)踐,尤其是對設(shè)計(jì)和代碼編碼方式有影響的那些。
第Ⅱ部分:敏捷設(shè)計(jì)。本部分討論面向?qū)ο筌浖O(shè)計(jì),包括它的定義,對復(fù)雜性進(jìn)行管理的問題和技術(shù),以及面向?qū)ο箢愒O(shè)計(jì)的原則。本部分最后用幾章描述了UML的一個實(shí)用子集。
第Ⅲ部分:案例學(xué)習(xí):Payroll系統(tǒng)。本部分描述面向?qū)ο笤O(shè)計(jì)和一個簡單的批處理Payroll系統(tǒng)的C++實(shí)現(xiàn)。前幾章描述本案例分析遇到的設(shè)計(jì)模式。最后一章是完整的案例分析,是本書最大和最完整的一個。
第Ⅳ部分:案例學(xué)習(xí):打包Payroll系統(tǒng)。本部分首先描述面向?qū)ο蟀O(shè)計(jì)的原則,然后通過增量打包上一部分的類來演示這些原則。最后幾章描述了Payroll應(yīng)用程序的數(shù)據(jù)庫和UI設(shè)計(jì)。
附錄A:兩家公司的諷刺故事
附錄B:Jack Reeves的“什么是軟件”一文。
如何使用本書
如果你是開發(fā)人員,請將本書從頭讀到尾。本書主要為開發(fā)人員而寫,包含以敏捷方式開發(fā)軟件所需的資訊。先學(xué)習(xí)實(shí)踐,然后是原則,然后是模式,然后是把所有這些結(jié)合起來的案例分析。整合所有這些知識將有助于你完成項(xiàng)目。
如果你是管理人員或業(yè)務(wù)分析師,請閱讀第Ⅰ部分“敏捷開發(fā)”。第1章~第6章深入討論了敏捷原則和實(shí)踐,從需求到計(jì)劃,再到測試、重構(gòu)和編程。本部分將指導(dǎo)你建立團(tuán)隊(duì)和管理項(xiàng)目。
如果想學(xué)習(xí)UML,請先閱讀第13章~第19章,然后閱讀第Ⅲ部分“案例學(xué)習(xí):薪水支付系統(tǒng)Payroll”的全部章節(jié)。這將幫助你在UML的語法和使用方面打下良好基礎(chǔ),同時(shí)幫助你在UML和C#之間轉(zhuǎn)換。
如果想學(xué)習(xí)設(shè)計(jì)模式,請閱讀第Ⅱ部分“敏捷設(shè)計(jì)”,從而先學(xué)習(xí)設(shè)計(jì)原則。然后閱讀第Ⅲ部分“案例學(xué)習(xí):薪水支付系統(tǒng)Payroll”和第Ⅳ部分“案例學(xué)習(xí):打包Payroll系統(tǒng)”。它們定義了所有模式,并展示了它們在典型情況下的使用。
如果想學(xué)習(xí)面向?qū)ο笤O(shè)計(jì)原則,請閱讀第Ⅱ部分“敏捷設(shè)計(jì)”和第Ⅲ部分“案例學(xué)習(xí):薪水支付系統(tǒng)Payroll”和第Ⅳ部分“案例學(xué)習(xí):打包Payroll系統(tǒng)”。它們描述了面向?qū)ο笤O(shè)計(jì)原則并展示了如何使用它們。
如果想學(xué)習(xí)敏捷開發(fā)方法,請閱讀第Ⅰ部分“敏捷開發(fā)”。本部分描述了敏捷開發(fā)的需求、計(jì)劃、測試、重構(gòu)和編程。
如果想找樂子,請閱讀附錄A“兩家公司的諷刺故事”。
(1)前言為兩名作者共同寫成,因而在“我”的后面指出了具體的作者名稱,以示區(qū)分。
(2)譯注:Grady Booch是統(tǒng)一建模語言(UML)的締造者之一。
(3)有4篇文章。前三篇是“Iterative and Incremental Development”(I, II, III)。最后一篇是“C.O.D.E Culled Object Development process”。
(4)譯注:沃德·坎寧安,Wiki概念的發(fā)明者,設(shè)計(jì)模式和敏捷軟件方法的先驅(qū)之一。
(5)http://c2.com/cgi/wiki包含涉及廣泛主題的大量文章。有數(shù)百上千的作者。有人說,也就Ward Cunningham才能用幾行Perl代碼發(fā)起一次社會革命。
(6)1995年到2001年任何可靠的學(xué)術(shù)著作采用的都肯定是“庫恩”(Kuhnian)一詞。它是指托馬斯·庫恩(Thomas S. Kuhn)所著的《科學(xué)革命的結(jié)構(gòu)》一書(芝加哥大學(xué)出版社1962年出版)。庫恩認(rèn)為科學(xué)不是通過新知識的線性積累進(jìn)步,而是經(jīng)歷周期性的革命,稱“范式轉(zhuǎn)移”。
(7)如果在文章中兩次提到庫恩的話,論文的可信度更高。
(8)Kent Beck著,中文版《實(shí)戰(zhàn)測試驅(qū)動開發(fā)》。
- Core Data應(yīng)用開發(fā)實(shí)踐指南
- Revit 2020中文版從入門到精通
- 移動Web實(shí)現(xiàn)指南:面向移動設(shè)備的網(wǎng)站優(yōu)化、開發(fā)和設(shè)計(jì)
- Spring Cloud Alibaba大型微服務(wù)架構(gòu)項(xiàng)目實(shí)戰(zhàn)(上冊)
- AIDevOps:智能微服務(wù)開發(fā)、運(yùn)維原理與實(shí)踐
- 負(fù)載均衡:高并發(fā)網(wǎng)關(guān)設(shè)計(jì)原理與實(shí)踐
- Spring in Action(第二版)中文版
- 測試開發(fā)實(shí)戰(zhàn)教程
- 軟件單元測試
- Android驅(qū)動開發(fā)與移植實(shí)戰(zhàn)詳解
- Spring 3.0就這么簡單
- ChatGPT驅(qū)動軟件開發(fā):AI在軟件研發(fā)全流程中的革新與實(shí)踐
- 軟件工程
- 數(shù)據(jù)壓縮入門
- Android移動應(yīng)用開發(fā)