《敏捷開(kāi)發(fā)(紀(jì)念版)》介紹敏捷原則、模式和實(shí)踐,包含4部分38章24個(gè)附錄,首先概述敏捷開(kāi)發(fā)、包含6個(gè)主題,分別為敏捷實(shí)踐、極限編程、規(guī)劃、測(cè)試、重構(gòu)和編程活動(dòng)。接下來(lái)介紹敏捷設(shè)計(jì),解釋了5個(gè)設(shè)計(jì)原則、UML及其應(yīng)用,包括狀態(tài)圖、對(duì)象圖、用例圖、序列圖和類(lèi)圖,并以一個(gè)完整的咖啡機(jī)編程案例來(lái)介紹具體的用法。通過(guò)薪水支付系統(tǒng)Payroll的實(shí)戰(zhàn)練習(xí),書(shū)中呈現(xiàn)了敏捷開(kāi)發(fā)的整個(gè)過(guò)程及其實(shí)用價(jià)值。 《敏捷開(kāi)發(fā)(紀(jì)念版)》適合真正想要通過(guò)敏捷方法來(lái)提升軟件開(kāi)發(fā)技能以及及時(shí)交付軟件價(jià)值的所有讀者閱讀和參考,尤其適合開(kāi)發(fā)、管理和業(yè)務(wù)分析崗位的人員學(xué)習(xí)。通過(guò)本書(shū)的閱讀,讀者還可以了解UML、設(shè)計(jì)模式、面向?qū)ο笤O(shè)計(jì)原則以及包括極限編程在內(nèi)的敏捷方法。
《敏捷開(kāi)發(fā)(紀(jì)念版)》通過(guò)豐富的案例來(lái)詮釋了敏捷開(kāi)發(fā)和敏捷設(shè)計(jì)的基礎(chǔ)知識(shí),介紹了UML模型如何轉(zhuǎn)為實(shí)際可用的C#代碼。在總體上概述敏捷運(yùn)動(dòng)之后,展示了敏捷實(shí)踐過(guò)程,并通過(guò)大量有價(jià)值的源代碼實(shí)例來(lái)展示了敏捷設(shè)計(jì)、開(kāi)發(fā)與實(shí)踐。
通過(guò)本書(shū)的閱讀,讀者可以掌握以下主題:
● 12個(gè)敏捷原則和14個(gè)極限編程實(shí)踐
● 技術(shù)預(yù)研,故事拆分,速率,迭代和版本規(guī)劃
● 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)、測(cè)試先行設(shè)計(jì)以及驗(yàn)收測(cè)試
● 單元測(cè)試與重構(gòu)
● 結(jié)對(duì)編程
● 敏捷設(shè)計(jì)與設(shè)計(jì)異味
● 5類(lèi)UML圖及其高效用法
● 面向?qū)ο蟮能浖O(shè)計(jì)及其設(shè)計(jì)模式
● 如何綜合運(yùn)用所有要點(diǎn)來(lái)實(shí)現(xiàn)一個(gè)真實(shí)的項(xiàng)目
可是老兄,你說(shuō)你去年就會(huì)完成這本書(shū)的。距離1999年Claudia發(fā)出這一正當(dāng)?shù)谋г梗呀?jīng)過(guò)去7年了,但我(Bob)(前言為兩名作者共同寫(xiě)成,因而在我的后面指出了具體的作者名稱,以示區(qū)分)覺(jué)得已經(jīng)做出了補(bǔ)償。我要經(jīng)營(yíng)一家咨詢公司,做大量編碼、培訓(xùn)、輔導(dǎo)和演講工作,寫(xiě)文章、專(zhuān)欄和博客,更不用提還要養(yǎng)家糊口并享受大家庭的樂(lè)趣。所以,這期間寫(xiě)三本書(shū)(每?jī)赡暌槐荆┱娴氖且粋(gè)巨大的挑戰(zhàn)。但是,我樂(lè)在其中。
敏捷開(kāi)發(fā)是在需求快速變化的情況下快速開(kāi)發(fā)軟件的一種能力。為實(shí)現(xiàn)這種敏捷性,需使用能提供必要紀(jì)律和反饋的實(shí)踐,需遵守保持軟件靈活且易于維護(hù)的設(shè)計(jì)原則,需知道已證明能為特定問(wèn)題權(quán)衡那些原則的設(shè)計(jì)模式。本書(shū)旨在將這三個(gè)概念整合成一個(gè)有機(jī)的整體。
本書(shū)介紹了這些原則、模式與實(shí)踐,然后通過(guò)多個(gè)案例來(lái)演示其實(shí)際運(yùn)用。更重要的是,這些案例都不是成品。相反,它們是進(jìn)行中的設(shè)計(jì)。你會(huì)看到設(shè)計(jì)人員犯錯(cuò),觀察到他們?nèi)绾伟l(fā)現(xiàn)并終糾正錯(cuò)誤,會(huì)看到設(shè)計(jì)人員對(duì)一個(gè)難題苦思不得其解,并擔(dān)心歧義和得失?傊憧吹降氖窃O(shè)計(jì)實(shí)際在進(jìn)行。
2005年初,我(Micah)在一個(gè)小開(kāi)發(fā)團(tuán)隊(duì)做事,當(dāng)時(shí)要著手用C#來(lái)寫(xiě)一個(gè).NET應(yīng)用程序。項(xiàng)目要求采用敏捷開(kāi)發(fā)實(shí)踐,這正是我進(jìn)入該項(xiàng)目的原因之一。雖然以前用過(guò)C#,但我熟悉的還是Java和C 。
當(dāng)時(shí)沒(méi)想過(guò)用.NET會(huì)有多大區(qū)別,事實(shí)證明確實(shí)如此。項(xiàng)目進(jìn)行了兩個(gè)月,我們發(fā)布了個(gè)版本。不是完整版本,只包含所有預(yù)期功能的一部分,但足夠用。他們也真的在用。僅過(guò)了兩個(gè)月,公司就從我們的開(kāi)發(fā)收獲了好處。管理層高興,嚷著要雇更多人,啟動(dòng)更多項(xiàng)目。
多年來(lái)一直出沒(méi)于敏捷社區(qū),我知道有許多敏捷開(kāi)發(fā)人員能幫到我們。我給他們打了電話,請(qǐng)他們加入。終,沒(méi)有任何一個(gè)搞敏捷的人加入我們的團(tuán)隊(duì)。為什么?或許重要的原因是我們用的是.NET。
幾乎所有敏捷開(kāi)發(fā)人員都有Java,C 或Smalltalk的背景。但幾乎沒(méi)聽(tīng)說(shuō)過(guò)有敏捷.NET程序員。我說(shuō)要用.NET進(jìn)行敏捷軟件開(kāi)發(fā),我的那些朋友可能根本沒(méi)有把我的話當(dāng)真,或者他們就是不想和.NET扯上關(guān)系。這是一個(gè)大問(wèn)題。而且,發(fā)生過(guò)好多次。
為期一周的有關(guān)各種軟件主題的課程使我能結(jié)識(shí)來(lái)自世界各地的開(kāi)發(fā)人員。
就各種軟件主題講授大約一周的課程,使我有機(jī)會(huì)接觸來(lái)自世界各地有代表性的開(kāi)發(fā)人員。許多學(xué)員都是.NET程序員,也有許多是Java或C 程序員。雖然不好聽(tīng),但根據(jù)我的經(jīng)驗(yàn),.NET程序員通常比Java和C 程序員要弱一些。顯然,并非總是如此。但通過(guò)在課堂上反復(fù)觀察,我只能得出這樣的結(jié)論:.NET程序員在敏捷軟件實(shí)踐、設(shè)計(jì)模式和設(shè)計(jì)原則等方面通常要弱一些。據(jù)我觀察,許多.NET程序員從未聽(tīng)說(shuō)過(guò)這些基本概念。這種情況必須改變!
我父親Robert C. Martin于2002年出版了的《敏捷軟件開(kāi)發(fā):原則、模式與實(shí)現(xiàn)》榮獲了2003年Jolt大獎(jiǎng)。那是本好書(shū),受到許多開(kāi)發(fā)人員的推崇。遺憾的是,它對(duì).NET社區(qū)影響甚微。雖然書(shū)的內(nèi)容同樣適合.NET,但鮮有.NET程序員讀過(guò)。
我希望講.NET的這一版能在.NET和開(kāi)發(fā)社區(qū)其余部分之間建立起一座橋梁。希望程序員能讀一讀,了解構(gòu)建軟件的更優(yōu)方式。希望他們開(kāi)始使用更好的軟件實(shí)踐,創(chuàng)建更好的設(shè)計(jì),提升.NET應(yīng)用程序員的質(zhì)量標(biāo)準(zhǔn)。希望.NET程序員不再比其他程序員弱。希望.NET程序員在軟件社區(qū)取得更多話語(yǔ)權(quán),就連Java開(kāi)發(fā)人員也樂(lè)意加入一個(gè).NET團(tuán)隊(duì)。
寫(xiě)書(shū)的過(guò)程中,我經(jīng)常糾結(jié)于要不要把我的名字放在一本.NET書(shū)的封面。這樣會(huì)不會(huì)將我和.NET聯(lián)系起來(lái),會(huì)不會(huì)有不好的暗示?但終我不再糾結(jié)。我是一名.NET程序員。不對(duì)!一名敏捷.NET程序員!我為此感到驕傲。
關(guān)于本書(shū)
20世紀(jì)90年代初,我(Bob)寫(xiě)了Designing Object-Oriented C Applications Using the Booch Method一書(shū),是我的代表作,我對(duì)其影響和銷(xiāo)量都很滿意。其實(shí)你現(xiàn)在正在看的開(kāi)始就是想作為那本書(shū)的第3版,只是后來(lái)完全不是那么回事。原作內(nèi)容在本書(shū)所剩無(wú)己,不超過(guò)3章,而且都進(jìn)行了大幅修訂。書(shū)的意圖、精神和許多啟發(fā)并沒(méi)有改變。在該書(shū)問(wèn)世后的十年里,我在軟件設(shè)計(jì)和開(kāi)發(fā)方面學(xué)到了很多。本書(shū)反映了我學(xué)到的東西。
這是怎樣的十年!該書(shū)是在互聯(lián)網(wǎng)時(shí)代之前出版的。互聯(lián)網(wǎng)問(wèn)世后,需要掌握的縮寫(xiě)詞數(shù)量大增。我們現(xiàn)在有了EJB、RMI、J2EE、XML、XSLT、HTML、ASP、JSP、ZOPE、SOAP、C#和.NET,另外還有設(shè)計(jì)模式、Java、Servelets和Application Servers;旧,要使本書(shū)所有章節(jié)的內(nèi)容保持是很難的。
本書(shū)和Booch的關(guān)系
1997年,Grady Booch(Grady Booch是統(tǒng)一建模語(yǔ)言(UML)的締造者之一)邀請(qǐng)我?guī)兔?xiě)他那本大獲成功的Object-Oriented Analysis and Design with Applications一書(shū)的第3版。我以前和Grady在一些項(xiàng)目上合作過(guò),是其許多作品(包括UML)的熱心讀者和內(nèi)容貢獻(xiàn)者。所以,我高興地接受了邀請(qǐng),并請(qǐng)我的好友Jim Newkirk共同參與。
接下來(lái)的兩年,我和Jim為Booch寫(xiě)了許多章節(jié),花在本書(shū)上的精力自然就少了。但是,我覺(jué)得Booch的書(shū)值得投入。另外,當(dāng)時(shí)還在想本書(shū)反正只是第2版,所以并不是特別上心。如果我要寫(xiě)一些有份量的內(nèi)容,我會(huì)寫(xiě)一些新的、不一樣的。
遺憾的是,Booch的書(shū)難產(chǎn)了。本來(lái)就很難在正常時(shí)間寫(xiě)書(shū),在互聯(lián)網(wǎng)泡沫的那段時(shí)間更是不太可能。Grady在Rational Software的工作更忙了,同時(shí)還忙于像Catapulse這樣的風(fēng)投企業(yè)。所以,項(xiàng)目陷入停頓。終,我問(wèn)Grady和Addison-Wesley出版社能不能把我和Jim寫(xiě)的章節(jié)放到本書(shū)。他們慷慨地同意了。本書(shū)的幾個(gè)案例分析和UML章節(jié)就是這么來(lái)的。
極限編程的影響
1998年末,極限編程(XP)嶄露頭角,挑戰(zhàn)我們對(duì)于軟件開(kāi)發(fā)的傳統(tǒng)觀念。是應(yīng)該在寫(xiě)任何代碼之前創(chuàng)建大量UML圖,還是避免一切形式的圖,直接寫(xiě)大量代碼?是應(yīng)該寫(xiě)許多說(shuō)明性的文檔來(lái)描述設(shè)計(jì),還是使代碼更具說(shuō)明性,從而無(wú)需輔助文檔?要結(jié)對(duì)寫(xiě)程序嗎?寫(xiě)生產(chǎn)代碼前要先寫(xiě)好測(cè)試代碼嗎?我們到底應(yīng)該怎么做?
這個(gè)變革來(lái)得恰是時(shí)候。20世紀(jì)90年代中期,Object Mentor幫助許多公司解決OO(面向?qū)ο?設(shè)計(jì)和項(xiàng)目管理問(wèn)題。我們幫這些公司完成其項(xiàng)目。在這個(gè)過(guò)程中,我們向團(tuán)隊(duì)灌輸了自己的態(tài)度與實(shí)踐。遺憾的是,這些東西沒(méi)有形成書(shū)面記錄。相反,只是從口頭上傳達(dá)給了客戶。
1998年,我意識(shí)到需要把我們的過(guò)程和實(shí)踐記錄下來(lái),以便更好地向客戶傳達(dá)。所以我在C Report上寫(xiě)了許多關(guān)于這一過(guò)程的文章(有4篇文章。前三篇是Iterative and Incremental Development(I, II, III)。后一篇是C.O.D.E Culled Object Development process)。但是,這些文章沒(méi)有達(dá)到目標(biāo)。信息量大,有時(shí)還十分有趣,但它們沒(méi)有將我們?cè)陧?xiàng)目中采用的實(shí)踐和態(tài)度整理成文,面是對(duì)數(shù)十年來(lái)我形成的價(jià)值觀的一種無(wú)意識(shí)的折衷。后是Kent Beck提醒了我。
本書(shū)和Kent的關(guān)系
1998年末,正當(dāng)我為Object Mentor過(guò)程的整理而煩惱時(shí),Kent和Beck在極限編程(XP)方面的成果讓我眼前一亮。這些成果散見(jiàn)于Ward Cunningham(沃德·坎寧安,Wiki概念的發(fā)明者,設(shè)計(jì)模式和敏捷軟件方法的先驅(qū)之一)的wiki(http://c2.com/cgi/wiki包含涉及廣泛主題的大量文章。有數(shù)百上千的作者。有人說(shuō),也就Ward Cunningham才能用幾行Perl代碼發(fā)起一次社會(huì)革命),和其他許多人的作品混在一起。盡管如此,作為一個(gè)有心人,我還是掌握了Kent的要點(diǎn)。感興趣的同時(shí),我也有了一些疑慮。極限編程的某些東西契合我的開(kāi)發(fā)過(guò)程目標(biāo)。但另一些東西,比如缺乏一個(gè)明確的設(shè)計(jì)階段,卻讓我疑惑。
我和Kent處于截然不同的軟件環(huán)境。他是公認(rèn)的Smalltalk顧問(wèn),我是公認(rèn)的C 顧問(wèn)。這兩個(gè)世界相互很難溝通,存在像庫(kù)恩范式(1995年到2001年任何可靠的學(xué)術(shù)著作采用的都肯定是庫(kù)恩(Kuhnian)一詞。它是指托馬斯·庫(kù)恩(Thomas S. Kuhn)所著的《科學(xué)革命的結(jié)構(gòu)》一書(shū)(芝加哥大學(xué)出版社1962年出版)。庫(kù)恩認(rèn)為科學(xué)不是通過(guò)新知識(shí)的線性積累進(jìn)步,而是經(jīng)歷周期性的革命,稱范式轉(zhuǎn)移。)那么大的鴻溝。
其他時(shí)候我絕不會(huì)邀請(qǐng)Kent為C Report撰稿。但是,由于我們對(duì)于過(guò)程的看法取得了一致,所以語(yǔ)言的鴻溝不再重要。1999年2月,我在慕尼黑的OOP大會(huì)上見(jiàn)到了Kent。我當(dāng)時(shí)在講OOD的原則,他就在對(duì)面的房間里講XP。由于沒(méi)法聽(tīng)到他的演講,我在午餐時(shí)找到了Kent。我們討論了XP,我提出了讓他為C Report撰稿的請(qǐng)求。這是一篇很棒的文章,討論了Kent如何和一名同事花一小時(shí)左右的時(shí)間在某個(gè)live system中進(jìn)行一次全面的設(shè)計(jì)更改。
接著幾個(gè)月,我慢慢梳理出了自己對(duì)XP的憂慮。擔(dān)心的是如何采納一個(gè)沒(méi)有明顯前期設(shè)計(jì)階段的過(guò)程。感覺(jué)自己好像卡在了這里。對(duì)于我的客戶及其整個(gè)行業(yè),我難道不應(yīng)該告訴他們值得花時(shí)間在設(shè)計(jì)上嗎?
后,我終于意識(shí)到自己都沒(méi)有真正注重過(guò)這樣的一個(gè)階段。即使在我寫(xiě)的關(guān)于設(shè)計(jì)、Booch圖和UML圖的所有文章和書(shū)里,都總是將代碼作為驗(yàn)證圖是否有意義的一種方式來(lái)使用。在我的所有客戶咨詢中,我會(huì)花一兩個(gè)小時(shí)幫客戶畫(huà)圖,再指導(dǎo)他們通過(guò)代碼來(lái)利用這些圖。我意識(shí)到雖然XP關(guān)于設(shè)計(jì)的說(shuō)法有點(diǎn)陌生,有點(diǎn)庫(kù)恩(如果在文章中兩次提到庫(kù)恩的話,論文的可信度更高),但其背后的實(shí)踐我本來(lái)就熟悉。
我對(duì)XP的其他擔(dān)心較容易解決。我私底下一直擁護(hù)結(jié)對(duì)編程。XP使我能光明正大地和伙伴一起編程。重構(gòu)、持續(xù)集成、在客戶現(xiàn)場(chǎng)工作……所有這些對(duì)我來(lái)說(shuō)都很容易接受。它們很接近我向客戶建議的工作方式。
XP的一個(gè)實(shí)踐對(duì)我來(lái)說(shuō)是新的發(fā)現(xiàn)。次聽(tīng)說(shuō)測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(Test-driven development,TDD)(Kent Beck著,中文版《實(shí)戰(zhàn)測(cè)試驅(qū)動(dòng)開(kāi)發(fā)》)時(shí)可能感覺(jué)沒(méi)什么:寫(xiě)生產(chǎn)代碼前先寫(xiě)好測(cè)試用例,寫(xiě)所有生產(chǎn)代碼的目的都是使失敗的測(cè)試用例通過(guò)測(cè)試。但是,我對(duì)這種開(kāi)發(fā)模式所帶來(lái)的深遠(yuǎn)影響始料未及。該實(shí)踐徹底改變了我寫(xiě)軟件的方式:變得更好了。
所以,1999年秋,我確信 Object Mentor 應(yīng)采納 XP 作為其選擇的過(guò)程,并且我應(yīng)該放棄寫(xiě)自己的過(guò)程的想法。Kent已經(jīng)很好地歸納了XP的實(shí)踐與過(guò)程,我的小小嘗試與之相比不值一提。
.NET
各大企業(yè)正在進(jìn)行一場(chǎng)戰(zhàn)爭(zhēng),目的是爭(zhēng)取你的效忠。它們認(rèn)為,只要擁有了語(yǔ)言,就擁有了程序員以及雇用這些程序員的公司。
這場(chǎng)戰(zhàn)爭(zhēng)的個(gè)爭(zhēng)奪點(diǎn)是Java。Java是個(gè)由大公司為贏得程序員關(guān)注而創(chuàng)建的語(yǔ)言,并取得了極大成功。Java在軟件社區(qū)深得人心,基本上是現(xiàn)代多層IT應(yīng)用程序的事實(shí)上的標(biāo)準(zhǔn)。
相應(yīng)的一個(gè)還擊來(lái)自IBM,它通過(guò)Eclipse開(kāi)發(fā)環(huán)境奪走了很大一塊Java市場(chǎng)。Microsoft技術(shù)精湛的開(kāi)發(fā)人員也不甘落后,他們提供了常規(guī)意義上的.NET和為特殊的C#。
令人驚訝的是,Java和C#很難區(qū)分。兩種語(yǔ)言語(yǔ)義一致,語(yǔ)法也相似,以至于許多代碼段沒(méi)有差別。雖然Microsoft在技術(shù)創(chuàng)新上差點(diǎn)意思,但它趕超別人并取得終勝利的能力還是相當(dāng)不錯(cuò)的。
本書(shū)版采用Java和C 作為編碼語(yǔ)言。本書(shū)則完全采用C#和.NET平臺(tái)。不要把這當(dāng)成是背書(shū)。這場(chǎng)戰(zhàn)爭(zhēng)我們不選邊站。事實(shí)上,大公司為爭(zhēng)奪程序員的關(guān)注而發(fā)起的戰(zhàn)爭(zhēng)沒(méi)有太大意義。未來(lái)幾年一旦出現(xiàn)更好的語(yǔ)言,程序員的心思立即就會(huì)發(fā)生轉(zhuǎn)移。
本書(shū)之所以出.NET版,自然是為了方便.NET讀者。雖然書(shū)中的原則、模式與實(shí)踐和語(yǔ)言無(wú)關(guān),但案例分析不是。.NET程序員看.NET的案例分析更舒服,Java程序員看Java的例子更愉快。
魔鬼就在細(xì)節(jié)里
本書(shū)包含大量.NET代碼。希望你能仔細(xì)讀代碼,因?yàn)榇a在很大程度上就是本書(shū)的重點(diǎn)。代碼具現(xiàn)了本書(shū)要表達(dá)的意思。
本書(shū)采用固定寫(xiě)作模式:大小不一的一系列案例分析。有的非常小,有的則需要用幾章來(lái)講解。每個(gè)案例分析都有一些前置材料,描述了該案例分析要用到的面向?qū)ο笤O(shè)計(jì)原則和模式。
本書(shū)首先討論開(kāi)發(fā)實(shí)踐和過(guò)程,其中穿插了許多小的案例分析和例子。然后開(kāi)始討論設(shè)計(jì)和設(shè)計(jì)原則,接著討論一些設(shè)計(jì)模式,對(duì)包進(jìn)行管控的更多設(shè)計(jì)原則,以及更多模式。所有這些主題都伴隨有相應(yīng)的案例分析。
所以,要做好讀一些代碼和研究一些UML圖的準(zhǔn)備。本書(shū)技術(shù)性很強(qiáng),它要傳授的經(jīng)驗(yàn)教訓(xùn)如同惡魔一樣隱藏在細(xì)節(jié)里(細(xì)節(jié)決定成敗)。
本書(shū)的結(jié)構(gòu)
本書(shū)包含4部分38章和2個(gè)附錄。
第Ⅰ部分:敏捷開(kāi)發(fā)。本部分描述敏捷開(kāi)發(fā)的概念。首先展示敏捷聯(lián)盟宣言,概述了極限編程(XP),然后通過(guò)許多小的案例分析來(lái)闡述一些單獨(dú)的XP實(shí)踐,尤其是對(duì)設(shè)計(jì)和代碼編碼方式有影響的那些。
第Ⅱ部分:敏捷設(shè)計(jì)。本部分討論面向?qū)ο筌浖O(shè)計(jì),包括它的定義,對(duì)復(fù)雜性進(jìn)行管理的問(wèn)題和技術(shù),以及面向?qū)ο箢?lèi)設(shè)計(jì)的原則。本部分后用幾章描述了UML的一個(gè)實(shí)用子集。
第Ⅲ部分:案例學(xué)習(xí):Payroll系統(tǒng)。本部分描述面向?qū)ο笤O(shè)計(jì)和一個(gè)簡(jiǎn)單的批處理Payroll系統(tǒng)的C 實(shí)現(xiàn)。前幾章描述本案例分析遇到的設(shè)計(jì)模式。后一章是完整的案例分析,是本書(shū)和完整的一個(gè)。
第Ⅳ部分:案例學(xué)習(xí):打包Payroll系統(tǒng)。本部分首先描述面向?qū)ο蟀O(shè)計(jì)的原則,然后通過(guò)增量打包上一部分的類(lèi)來(lái)演示這些原則。后幾章描述了Payroll應(yīng)用程序的數(shù)據(jù)庫(kù)和UI設(shè)計(jì)。
附錄A:兩家公司的諷刺故事
附錄B:Jack Reeves的什么是軟件一文。
如何使用本書(shū)
如果你是開(kāi)發(fā)人員,請(qǐng)將本書(shū)從頭讀到尾。本書(shū)主要為開(kāi)發(fā)人員而寫(xiě),包含以敏捷方式開(kāi)發(fā)軟件所需的資訊。先學(xué)習(xí)實(shí)踐,然后是原則,然后是模式,然后是把所有這些結(jié)合起來(lái)的案例分析。整合所有這些知識(shí)將有助于你完成項(xiàng)目。
如果你是管理人員或業(yè)務(wù)分析師,請(qǐng)閱讀第Ⅰ部分敏捷開(kāi)發(fā)。第1章~第6章深入討論了敏捷原則和實(shí)踐,從需求到計(jì)劃,再到測(cè)試、重構(gòu)和編程。本部分將指導(dǎo)你建立團(tuán)隊(duì)和管理項(xiàng)目。
如果想學(xué)習(xí)UML,請(qǐng)先閱讀第13章~第19章,然后閱讀第Ⅲ部分案例學(xué)習(xí):薪水支付系統(tǒng)Payroll的全部章節(jié)。這將幫助你在UML的語(yǔ)法和使用方面打下良好基礎(chǔ),同時(shí)幫助你在UML和C#之間轉(zhuǎn)換。
如果想學(xué)習(xí)設(shè)計(jì)模式,請(qǐng)閱讀第Ⅱ部分敏捷設(shè)計(jì),從而先學(xué)習(xí)設(shè)計(jì)原則。然后閱讀第Ⅲ部分案例學(xué)習(xí):薪水支付系統(tǒng)Payroll和第Ⅳ部分案例學(xué)習(xí):打包Payroll系統(tǒng)。它們定義了所有模式,并展示了它們?cè)诘湫颓闆r下的使用。
如果想學(xué)習(xí)面向?qū)ο笤O(shè)計(jì)原則,請(qǐng)閱讀第Ⅱ部分敏捷設(shè)計(jì)和第Ⅲ部分案例學(xué)習(xí):薪水支付系統(tǒng)Payroll和第Ⅳ部分案例學(xué)習(xí):打包Payroll系統(tǒng)。它們描述了面向?qū)ο笤O(shè)計(jì)原則并展示了如何使用它們。
如果想學(xué)習(xí)敏捷開(kāi)發(fā)方法,請(qǐng)閱讀第Ⅰ部分敏捷開(kāi)發(fā)。本部分描述了敏捷開(kāi)發(fā)的需求、計(jì)劃、測(cè)試、重構(gòu)和編程。
如果想找樂(lè)子,請(qǐng)閱讀附錄A兩家公司的諷刺故事。
羅伯特·C.馬丁
(Robert C. Martin)
業(yè)內(nèi)人士尊稱的鮑勃大叔(Uncle Bob),是國(guó)際知名的軟件工程師和導(dǎo)師,一位有五十多年健康編碼經(jīng)驗(yàn)的程序員。cleancoders.com聯(lián)合創(chuàng)始人和UncleBob咨詢公司創(chuàng)始人,主要提供軟件咨詢、技能培訓(xùn)和視頻教學(xué)服務(wù)。
他在專(zhuān)業(yè)技術(shù)領(lǐng)域具有較深的造詣。除了擔(dān)任C Report雜志的總編輯,他還發(fā)表了大量有影響力的文章,受邀在許多國(guó)際性軟件大會(huì)上發(fā)表演講。他是SOLID五大原則的奠基人,是《敏捷宣言》聯(lián)合簽署人并擔(dān)任過(guò)敏捷聯(lián)盟屆主席。他擅長(zhǎng)的主題有軟件匠藝、敏捷軟件開(kāi)發(fā)和測(cè)試驅(qū)動(dòng)開(kāi)發(fā)等。
馬丁是個(gè)終生學(xué)習(xí)者,52年出生的他,還在考飛行駕照。
米咖·馬丁
(Micah Martin)
軟件工程師、咨詢顧問(wèn)、培訓(xùn)師,擅長(zhǎng)的領(lǐng)域有面向?qū)ο笤O(shè)計(jì)原則與模式、敏捷軟件開(kāi)發(fā)實(shí)踐。他是開(kāi)源項(xiàng)目FitNesse項(xiàng)目的創(chuàng)始人和開(kāi)發(fā)總監(jiān)。他著述頗豐,同時(shí)也是很多軟件大會(huì)的演講嘉賓。
詳細(xì)目錄
第Ⅰ部分 敏捷開(kāi)發(fā)
第1章 敏捷實(shí)踐 002
敏捷聯(lián)盟 003
個(gè)人和互動(dòng)優(yōu)先于過(guò)程和工具 004
可以工作的軟件優(yōu)先于詳盡的文檔 004
客戶合作優(yōu)先于合同談判 005
應(yīng)對(duì)變化優(yōu)先于遵循計(jì)劃 006
原則 007
小結(jié) 009
參考文獻(xiàn) 010
第2章 極限編程概述 011
極限編程實(shí)踐 011
完整的團(tuán)隊(duì) 011
用戶故事 012
短的周期 012
驗(yàn)收測(cè)試 013
結(jié)對(duì)編程 014
測(cè)試驅(qū)動(dòng)開(kāi)發(fā) 015
集體所有權(quán) 015
持續(xù)集成 016
可持續(xù)的開(kāi)發(fā)速度 016
開(kāi)放的工作空間 017
規(guī)劃游戲 017
簡(jiǎn)單設(shè)計(jì) 018
重構(gòu) 019
隱喻 019
小結(jié) 020
參考文獻(xiàn) 021
第3章 計(jì)劃 022
初探 023
技術(shù)預(yù)研、故事拆分和速率 023
發(fā)布計(jì)劃 024
迭代計(jì)劃 024
定義完成 025
任務(wù)計(jì)劃 025
迭代 027
跟蹤 027
小結(jié) 028
參考文獻(xiàn) 029
第4章 測(cè)試 030
測(cè)試驅(qū)動(dòng)開(kāi)發(fā) 030
驗(yàn)收測(cè)試 035
意外獲得的架構(gòu) 037
小結(jié) 037
參考文獻(xiàn) 038
第5章 重構(gòu) 039
素?cái)?shù)產(chǎn)生程序:一個(gè)簡(jiǎn)單的重構(gòu)示例 040
重構(gòu) 043
后檢查 049
小結(jié) 053
參考文獻(xiàn) 054
第6章 一次編程實(shí)踐 055
保齡球比賽 056
小結(jié) 106
保齡球規(guī)則概述 107
第Ⅱ部分 敏捷設(shè)計(jì)
臭味和原則 110
參考文獻(xiàn) 110
第7章 什么是敏捷設(shè)計(jì) 111
設(shè)計(jì)臭味 112
設(shè)計(jì)的臭味:軟件腐化的氣味 112
僵化 113
脆弱 113
頑固 113
粘滯 114
不必要的復(fù)雜 114
不必要的重復(fù) 114
晦澀 115
為什么軟件會(huì)腐化 115
Copy程序 116
一個(gè)熟悉的場(chǎng)景 116
Copy程序的敏捷設(shè)計(jì) 120
小結(jié) 122
參考文獻(xiàn) 123
第8章 單一職責(zé)原則(SRP) 124
定義職責(zé) 126
分離耦合的職責(zé) 127
持久化 128
小結(jié) 128
參考文獻(xiàn) 129
第9章 開(kāi)/關(guān)原則(OCP) 130
描述 131
Shape應(yīng)用程序 133
違反OCP 133
遵循OCP 136
預(yù)測(cè)變化和貼切的結(jié)構(gòu) 138
放置鉤子 139
使用抽象獲得顯式封閉性 140
使用數(shù)據(jù)驅(qū)動(dòng)的方法獲取
封閉性 141
小結(jié) 142
參考文獻(xiàn) 143
第10章 里氏替換原則(LSP) 144
違反LSP的情形 145
更微妙的違反情形 147
一個(gè)實(shí)際的例子 154
用提取公共部分的方法代替繼承 158
啟發(fā)式規(guī)則和習(xí)慣用法 162
小結(jié) 162
參考文獻(xiàn) 163
第11章 依賴倒置原則(DIP) 164
層次化 165
倒置的接口所有權(quán) 166
依賴于抽象 167
一個(gè)簡(jiǎn)單的DIP例子 168
找出底層抽象 169
熔爐示例 171
小結(jié) 172
參考文獻(xiàn) 173
第12章 接口隔離原則(ISP) 174
接口污染 174
分離客戶端就是分離接口 176
類(lèi)接口和對(duì)象接口 177
通過(guò)委托來(lái)分離接口 178
使用多重繼承隔離接口 179
ATM 用戶界面的例子 180
小結(jié) 187
參考文獻(xiàn) 187
第13章 C#程序員UML概述(C#語(yǔ)言) 188
類(lèi)圖 191
對(duì)象圖 193
順序圖 193
協(xié)作圖 194
狀態(tài)圖 195
小結(jié) 196
參考文獻(xiàn) 196
第14章 使用UML 197
為什么建模 197
為什么要建軟件模型 198
寫(xiě)代碼之前是否應(yīng)該做好詳細(xì)設(shè)計(jì) 198
有效使用UML 199
與他人交流 199
脈絡(luò)圖 201
項(xiàng)目結(jié)束文檔 202
要保留的和要丟棄的 203
迭代式改進(jìn) 204
行為優(yōu)先 204
檢查結(jié)構(gòu) 206
想象代碼 208
圖示的演化 209
何時(shí)以及如何繪制圖示 210
何時(shí)要畫(huà)圖,何時(shí)不要畫(huà)圖 210
CASE工具 211
那么,文檔呢 212
小結(jié) 212
第15章 狀態(tài)圖 214
基礎(chǔ)知識(shí) 214
特定事件 216
超狀態(tài) 217
初始偽狀態(tài)和結(jié)束偽狀態(tài) 218
使用FSM圖示 219
小結(jié) 220
第16章 對(duì)象圖 221
即時(shí)快照 221
主動(dòng)對(duì)象 223
小結(jié) 227
第17章 用例 228
寫(xiě)用例 229
備選流程 230
其他東西呢 230
用例圖 231
小結(jié) 232
參考文獻(xiàn) 232
第18章 順序圖 233
基礎(chǔ)知識(shí) 234
對(duì)象、生命線、消息及其他 234
創(chuàng)建和析構(gòu) 235
簡(jiǎn)單循環(huán) 236
時(shí)機(jī)和場(chǎng)合 237
高級(jí)概念 240
循環(huán)和條件 240
耗費(fèi)時(shí)間的消息 241
異步消息 243
多線程 248
主動(dòng)對(duì)象 249
向接口發(fā)送消息 250
小結(jié) 251
第19章 類(lèi)圖 252
基礎(chǔ)知識(shí) 253
類(lèi) 253
關(guān)聯(lián) 253
繼承 254
類(lèi)圖示例 255
細(xì)節(jié) 258
類(lèi)的衍型 258
抽象類(lèi) 259
屬性 260
聚合 260
組合 261
多重性 263
關(guān)聯(lián)衍型 263
嵌套類(lèi) 264
關(guān)聯(lián)類(lèi) 265
關(guān)聯(lián)修飾符 266
小結(jié) 266
參考文獻(xiàn) 266
第20章 咖啡的啟示 267
Mark IV型專(zhuān)用咖啡機(jī) 267
規(guī)格說(shuō)明書(shū) 268
常見(jiàn)的丑陋方案 271
虛構(gòu)的抽象 273
改進(jìn)方案 275
實(shí)現(xiàn)抽象模型 279
這個(gè)設(shè)計(jì)的好處 295
面向?qū)ο筮^(guò)度設(shè)計(jì) 303
參考文獻(xiàn) 304
第21章 命令模式和主動(dòng)對(duì)象模式 310
簡(jiǎn)單的命令模式 311
事務(wù)操作 313
實(shí)體上的解耦和時(shí)間上的解耦 314
時(shí)間上的解耦 315
UNDO()方法 315
主動(dòng)對(duì)象模式 316
小結(jié) 322
參考文獻(xiàn) 322
第22章 模板方法模式和策略模式:繼承和委托 323
模板方法模式 324
模式濫用 327
冒泡排序 328
策略模式 332
小結(jié) 338
參考文獻(xiàn) 338
第23章 外觀模式和中介者模式 339
外觀模式 339
中介者模式 340
小結(jié) 343
參考文獻(xiàn) 343
第24章 單例模式和單狀態(tài)模式 344
單例模式 345
好處 347
代價(jià) 347
單例模式實(shí)戰(zhàn) 348
單狀態(tài)模式 350
好處 351
代價(jià) 352
單狀態(tài)模式實(shí)戰(zhàn) 352
小結(jié) 358
參考文獻(xiàn) 359
第25章 空對(duì)象模式 360
描述 360
小結(jié) 363
參考文獻(xiàn) 364
第26章 案例學(xué)習(xí):Payroll系統(tǒng)的輪迭代 365
規(guī)格說(shuō)明書(shū) 366
基于用例進(jìn)行分析 367
添加新員工 368
刪除員工 369
提交考勤卡 370
提交銷(xiāo)售憑證 370
提交工會(huì)服務(wù)費(fèi) 371
更改員工信息 372
薪水支付日 374
反思:我們從中學(xué)到了什么 376
薪水支付類(lèi)別抽象 376
支付薪水時(shí)間表抽象 377
第Ⅲ部分 案例學(xué)習(xí):薪水支付系統(tǒng)Payroll
支付方式 378
工會(huì)所屬關(guān)系 378
小結(jié) 379
參考文獻(xiàn) 380
第27章 案例學(xué)習(xí):Payroll系統(tǒng)
實(shí)現(xiàn) 381
事務(wù) 381
添加員工 382
Payoll系統(tǒng)的數(shù)據(jù)庫(kù) 384
刪除雇員 388
考勤卡、銷(xiāo)售憑證和服務(wù)費(fèi)用 390
更改員工信息 399
更改員工類(lèi)別 403
我犯了什么暈? 409
支付員工薪水 413
我們是否希望開(kāi)發(fā)人員來(lái)做商業(yè)決策? 415
按月薪結(jié)算的員工支付薪水 415
支付小時(shí)工的薪水 418
主程序 431
數(shù)據(jù)庫(kù) 432
小結(jié) 433
關(guān)于本章 433
參考文獻(xiàn) 434
第Ⅳ部分 案例學(xué)習(xí):打包Payroll系統(tǒng)
第28章 包和組件的設(shè)計(jì)原則 436
包和組件 436
組件的內(nèi)聚性原則:粒度 437
重用-發(fā)布等價(jià)原則(REP) 438
共同重用原則(CRP) 439
共同封閉原則(CCP) 440
組件內(nèi)聚性小結(jié) 441
組件耦合原則:穩(wěn)定性 441
無(wú)環(huán)依賴原則(ADP) 441
穩(wěn)定依賴原則(SDP) 447
穩(wěn)定抽象原則(SAP) 452
小結(jié) 456
第29章 工廠模式 457
依賴問(wèn)題 460
靜態(tài)類(lèi)型與動(dòng)態(tài)類(lèi)型 461
可替換的工廠 462
對(duì)測(cè)試支架使用對(duì)象工廠 463
工廠模式的重要性 465
小結(jié) 465
參考文獻(xiàn) 465
第30章 案例學(xué)習(xí):Payroll系統(tǒng)的包分析 466
組件結(jié)構(gòu)和符號(hào) 467
應(yīng)用共同封閉原則(CCP) 469
應(yīng)用發(fā)布等價(jià)原則(REP) 471
耦合和封裝 474
度量指標(biāo) 475
在薪水支付系統(tǒng)中使用這些度量 477
對(duì)象工廠 479
重新思考內(nèi)聚的邊界 483
終的包結(jié)構(gòu) 483
小結(jié) 485
參考文獻(xiàn) 485
第31章 組合模式 487
組合命令 489
多重性還是非多重性 490
小結(jié) 490
第32章 觀察者模式 491
數(shù)字時(shí)鐘 492
觀察者模式 512
模型 513
觀察者模式與面向?qū)ο笤O(shè)計(jì)原則 514
小結(jié) 514
參考文獻(xiàn) 515
第33章 抽象服務(wù)器、適配器和橋接模式 516
抽象服務(wù)器模式 517
適配器模式 518
類(lèi)形式的適配器 519
調(diào)制解調(diào)器問(wèn)題、適配器和里氏替換原則 520
橋接模式 524
小結(jié) 527
參考文獻(xiàn) 527
第34章 代理模式和TDG模式:管理第三方API 528
代理模式 529
代理購(gòu)物車(chē)應(yīng)用 534
小結(jié) 550
處理數(shù)據(jù)庫(kù)、中間件以及其他第三方
接口 550
TDG模式 553
測(cè)試和內(nèi)存TDG 561
測(cè)試DbGateway 562
小結(jié) 568
參考文獻(xiàn) 568
第35章 訪問(wèn)者模式 569
訪問(wèn)者模式 570
非循環(huán)訪問(wèn)者模式 575
使用訪問(wèn)者模式 581
訪問(wèn)者模式的其他用途 589
裝飾者模式 589
擴(kuò)展對(duì)象模式 596
小結(jié) 610
參考文獻(xiàn) 610
第36章 狀態(tài)模式 611
嵌套語(yǔ)句switch/case 612
內(nèi)部作用域內(nèi)有效的狀態(tài)變量 615
測(cè)試動(dòng)作 616
代價(jià)和好處 616
遷移表 617
使用表解釋 618
代價(jià)和收益 619
狀態(tài)模式 620
狀態(tài)模式和策略模式 624
使用狀態(tài)模式的代價(jià)和好處 624
SMC(狀態(tài)機(jī)編譯器) 625
SMC生成的Turnstile.cs以及其他
支持文件 628
代價(jià)和收益 634
狀態(tài)機(jī)的應(yīng)用場(chǎng)合 634
作為 GUI 中的高層應(yīng)用策略 634
GUI 交互控制器 636
分布式處理 637
小結(jié) 638
參考文獻(xiàn) 639
第37章 案例學(xué)習(xí):Payroll系統(tǒng)的數(shù)據(jù)庫(kù) 640
建立數(shù)據(jù)庫(kù) 641
代碼設(shè)計(jì)中的一個(gè)缺陷 642
增加雇員 644
事務(wù) 658
加載Employee對(duì)象 665
還有什么工作? 680
第38章 案例學(xué)習(xí):Payroll系統(tǒng)的用戶界面 681
界面 683
實(shí)現(xiàn) 684
構(gòu)建窗口 696
Payroll的窗口 705
真面目 720
小結(jié) 720
參考 721
Rupert:Alpha項(xiàng)目 722
附錄A 兩家公司的諷刺故事 722
附錄B 源碼即設(shè)計(jì) 739