學(xué)習(xí)完整課程請(qǐng)移步 互聯(lián)網(wǎng) Java 全棧工程師
本節(jié)視頻
概述
敏捷方法論有一個(gè)共同的特點(diǎn),那就是都將矛頭指向了“文檔”,它們認(rèn)為傳統(tǒng)的軟件工程方法文檔量太“重”了,稱為“重量級(jí)”方法,而相應(yīng)的敏捷方法則是“輕量級(jí)”方法。正是因?yàn)椤拜p量級(jí)”感覺(jué)沒(méi)有什么力量,不但不能夠有效體現(xiàn)靈活性,反而顯得是不解決問(wèn)題的方法論似的。因此,就有了一次劃時(shí)代的會(huì)議,創(chuàng)建了敏捷聯(lián)盟。
在敏捷方法論領(lǐng)域中,比較知名的、有影響力的,是擁有與 Microsoft 的操作系統(tǒng)相同縮寫(xiě)語(yǔ)——XP的極限編程(eXtreme Programming)。極限編程方法論可以說(shuō)是敏捷聯(lián)盟中最鮮艷的一面旗幟,也是被研究、嘗試、應(yīng)用、贊揚(yáng)、批判最多的一種方法論,也是相對(duì)來(lái)說(shuō)最成熟的一種。
這一被譽(yù)為“黑客文化”的方法論的雛形最初形成于1996—1999年間,Kent Beck、Ward Cunninggham、Ron Jeffrey 在開(kāi)發(fā) C3 項(xiàng)目(Chrysler Comprehensive Compensation)的實(shí)踐中總結(jié)出了 XP 的基本元素。在此之后,Kent Beck 和他的一些好朋友們一起在實(shí)踐中完善提高,終于形成了極限編程方法論。
解析極限編程
那么什么是 XP 呢?XP 是一種輕量(敏捷)、高效、低風(fēng)險(xiǎn)、柔性、可預(yù)測(cè)、科學(xué)而且充滿樂(lè)趣的軟件開(kāi)發(fā)方式。與其他方法論相比,其最大的不同在于:
- 在更短的周期內(nèi),更早地提供具體、持續(xù)的反饋信息。
- 在迭代的進(jìn)行計(jì)劃編制,首先在最開(kāi)始迅速生成一個(gè)總體計(jì)劃,然后在整個(gè)項(xiàng)目開(kāi)發(fā)過(guò)程中不斷的發(fā)展它。
- 依賴于自動(dòng)測(cè)試程序來(lái)監(jiān)控開(kāi)發(fā)進(jìn)度,并及早地捕獲缺陷。
- 依賴于口頭交流、測(cè)試和源程序進(jìn)行溝通。
- 倡導(dǎo)持續(xù)的演化式設(shè)計(jì)。
- 依賴于開(kāi)發(fā)團(tuán)隊(duì)內(nèi)部的緊密協(xié)作。
- 盡可能達(dá)到程序員短期利益和項(xiàng)目長(zhǎng)期利益的平衡。
Kent Beck 曾經(jīng)說(shuō)過(guò)“開(kāi)車”就是一個(gè) XP 的范例,即使看上去進(jìn)行得很順利,也不要把視線從公路上移開(kāi),因?yàn)槁窙r的變化,將使得你必須隨時(shí)做出一些這樣那樣的調(diào)整。而在軟件項(xiàng)目中,客戶就是司機(jī),他們也沒(méi)有辦法確切地知道軟件應(yīng)該做什么,因此程序員就需要向客戶提供方向盤(pán),并且告知我們現(xiàn)在的位置。
XP 包括寫(xiě)什么呢?如圖,XP 由價(jià)值觀、原則、實(shí)踐和行為四個(gè)部分組成,它們彼此相互依賴、關(guān)聯(lián), 并通過(guò)行為貫穿于整個(gè)生命期。
四大價(jià)值觀
XP 的核心是其總結(jié)的溝通(Communication)、簡(jiǎn)單(Simplicity)、反饋(Feedback)、勇氣(Courage)四大價(jià)值觀,它們是XP的基礎(chǔ),也是XP的靈魂。
此外還擴(kuò)展了第五個(gè)價(jià)值觀:謙遜(Modesty)。 XP用“溝通、簡(jiǎn)單、反饋、勇氣和謙遜”來(lái)減輕開(kāi)發(fā)壓力和包袱;XP 精神可以啟發(fā)我們?nèi)绾螌W(xué)習(xí)和對(duì)待快速變化、多樣的開(kāi)發(fā)技術(shù)。成功學(xué)習(xí) XP 的關(guān)鍵,是用“溝通、簡(jiǎn)單、反饋、勇氣和謙遜”的態(tài)度來(lái)對(duì)待 XP;輕松愉快地來(lái)感受 XP 的實(shí)踐思想;自己認(rèn)真實(shí)踐后,通過(guò)對(duì)真實(shí)反饋的分析,來(lái)決定 XP 對(duì)自己的價(jià)值;有勇氣接受它,或改進(jìn)它。
溝通
通常程序員給人留下的印象就是“內(nèi)向、不善言談”,然后項(xiàng)目中的許多問(wèn)題就出在這些缺乏溝通的開(kāi)發(fā)人員身上。經(jīng)常由于某個(gè)程序員做出了一個(gè)設(shè)計(jì)決定,但是卻不能及時(shí)地通知大家,結(jié)果使得大家在協(xié)作與配合上出現(xiàn)了很多的麻煩,而在傳統(tǒng)的方法論中,并不在意這種口頭溝通不暢的問(wèn)題,而是希望借助于完善的流程和面面俱到的文檔、報(bào)表、計(jì)劃來(lái)替代,但是這同時(shí)又引入了效率不高的新問(wèn)題。
XP 方法論認(rèn)為,如果小組成員之間無(wú)法做到持續(xù)的、無(wú)間斷的交流,那么協(xié)作就無(wú)從談起,從這個(gè)角度能夠發(fā)現(xiàn),通過(guò)文檔、報(bào)表等人工制品進(jìn)行交流面臨巨大的局限性。因此,XP 組合了諸如對(duì)編程這樣的最佳實(shí)踐,鼓勵(lì)大家進(jìn)行口頭交流,通過(guò)交流解決問(wèn)題,提高效率。
簡(jiǎn)單
XP 方法論提倡在工作中秉承“夠用就好”的思路,也就是盡量地簡(jiǎn)單化,只要今天夠用就行,不考慮明天會(huì)發(fā)現(xiàn)的新問(wèn)題。這一點(diǎn)看上去十分容易,但是要真正做到保持簡(jiǎn)單的工作其實(shí)很難的。因?yàn)樵趥鹘y(tǒng)的開(kāi)發(fā)方法中,都要求大家對(duì)未來(lái)做一些預(yù)先規(guī)劃,以便對(duì)今后可能發(fā)生的變化預(yù)留一些擴(kuò)展的空間。
正如對(duì)傳統(tǒng)開(kāi)發(fā)方法的認(rèn)識(shí)一樣,許多開(kāi)發(fā)人員也會(huì)質(zhì)疑 XP,保持系統(tǒng)的擴(kuò)展性很重要,如果都保持簡(jiǎn)單,那么如何使得系統(tǒng)能夠有良好的擴(kuò)展性呢?其實(shí)不然,保持簡(jiǎn)單的理由有兩個(gè):
- 開(kāi)發(fā)小組在開(kāi)發(fā)時(shí)所做的規(guī)劃,并無(wú)法保證其符合客戶需要的,因此做的大部分工作都將落空,使得開(kāi)發(fā)過(guò)程中重復(fù)的、沒(méi)有必要的工作增加,導(dǎo)致整體效率降低。
- 另外,在 XP 中提倡時(shí)刻對(duì)代碼進(jìn)行重構(gòu),一直保持其良好的結(jié)構(gòu)與可擴(kuò)展性。也就是說(shuō),可擴(kuò)展性和為明天設(shè)計(jì)并不是同一個(gè)概念,XP 是反對(duì)為明天考慮而工作,并不是說(shuō)代碼要失去擴(kuò)展性
而且簡(jiǎn)單和溝通之間還有一種相對(duì)微妙的相互支持關(guān)系。當(dāng)一個(gè)團(tuán)隊(duì)之間,溝通的越多,那么就越容易明白哪些工作需要做,哪些工作不需要做。另一方面,系統(tǒng)越簡(jiǎn)單,需要溝通的內(nèi)容也就越少,溝通也將更加全面。
反饋
是什么原因使得我們的客戶、管理層這么不理解開(kāi)發(fā)團(tuán)隊(duì)?為什么客戶、管理層總是喜歡給我們一個(gè)死亡之旅?究其癥結(jié),就是開(kāi)發(fā)的過(guò)程中缺乏必要的反饋。在許許多多項(xiàng)目中,當(dāng)開(kāi)發(fā)團(tuán)隊(duì)經(jīng)歷過(guò)了需求分析階段之后,在相當(dāng)長(zhǎng)的一段時(shí)間內(nèi),是沒(méi)有任何反饋信息的。整個(gè)開(kāi)發(fā)過(guò)程對(duì)于客戶和管理層而言就像一個(gè)黑盒子,進(jìn)度完全是不可見(jiàn)的。
而且在項(xiàng)目的過(guò)程中,這樣的現(xiàn)象不僅出現(xiàn)在開(kāi)發(fā)團(tuán)隊(duì)與客戶、管理層之間,還包括在開(kāi)發(fā)團(tuán)隊(duì)內(nèi)部。這一切問(wèn)題都需要我們更加注重反饋。,反饋對(duì)于任何軟件項(xiàng)目的成功都是至關(guān)重要的,而在 XP 方法論中則更進(jìn)一步,通過(guò)持續(xù)、明確的反饋來(lái)暴露軟件狀態(tài)的問(wèn)題。具體而言就是:
- 在開(kāi)發(fā)團(tuán)隊(duì)內(nèi)部,通過(guò)提前編寫(xiě)單元測(cè)試代碼,時(shí)時(shí)反饋代碼的問(wèn)題與進(jìn)展。
- 在開(kāi)發(fā)過(guò)程中,還應(yīng)該加強(qiáng)集成工作,做到持續(xù)集成,使得每一次增量都是一個(gè)可執(zhí)行的工作版本,也就是逐漸是軟件長(zhǎng)大,整個(gè)過(guò)程中,應(yīng)該通過(guò)向客戶和管理層演示這些可運(yùn)行的版本,以便及早地反饋,及早地發(fā)現(xiàn)問(wèn)題。
同時(shí),我們也會(huì)發(fā)現(xiàn)反饋與溝通也有著良好的配合,及時(shí)和良好的反饋有助于溝通。而簡(jiǎn)單的系統(tǒng)更有利于測(cè)試和反饋。
勇氣
在應(yīng)用 XP 方法論時(shí),我們每時(shí)每刻都在應(yīng)對(duì)變化:由于溝通良好,因此會(huì)有更多需求變更的機(jī)會(huì);由于時(shí)刻保持系統(tǒng)的簡(jiǎn)單,因此新的變化會(huì)帶來(lái)一些重新開(kāi)發(fā)的需要;由于反饋及時(shí),因此會(huì)有更多中間打斷你的思路的新需求。
總之這一切,使得你立刻處于變化之中,因此這時(shí)就需要你有勇氣來(lái)面對(duì)快速開(kāi)發(fā),面對(duì)可能的重新開(kāi)發(fā)。也許你會(huì)覺(jué)得,為什么要讓我們的開(kāi)發(fā)變得如此零亂,但是其實(shí)這些變化若你不讓它早暴露,那么它就會(huì)遲一些出現(xiàn),并不會(huì)因此消亡,因此,XP 方法論讓它們?cè)绯霈F(xiàn)、早解決,是實(shí)現(xiàn)“小步快走”開(kāi)發(fā)節(jié)奏的好辦法。
也就是 XP 方法論要求開(kāi)發(fā)人員穿上強(qiáng)大、自動(dòng)測(cè)試的盔甲,勇往直前,在重構(gòu)、編碼規(guī)范的支持下,有目的地快速開(kāi)發(fā)。
勇氣可以來(lái)源于溝通,因?yàn)樗沟酶唢L(fēng)險(xiǎn)、高回報(bào)的試驗(yàn)成為可能;勇氣可以來(lái)源于簡(jiǎn)單,因?yàn)槊鎸?duì)簡(jiǎn)單的系統(tǒng),更容易鼓起勇氣;勇氣可以來(lái)源于反饋,因?yàn)槟憧梢约皶r(shí)獲得每一步前進(jìn)的狀態(tài)(自動(dòng)測(cè)試),會(huì)使得你更勇于重構(gòu)代碼。
四大價(jià)值觀之外
在這四大價(jià)值觀之下,隱藏著一個(gè)更深刻的東西,那就是尊重。因?yàn)檫@一切都建立在團(tuán)隊(duì)成員之間的相互關(guān)心、相互理解的基礎(chǔ)之上。
5 個(gè)原則
快速反饋
及時(shí)地、快速地獲取反饋,并將所學(xué)到的知識(shí)盡快地投入到系統(tǒng)中去。也就是指開(kāi)發(fā)人員應(yīng)該通過(guò)較短的反饋循環(huán)迅速地了解現(xiàn)在的產(chǎn)品是否滿足了客戶的需求。這也是對(duì)反饋這一價(jià)值觀的進(jìn)一步補(bǔ)充。
簡(jiǎn)單性假設(shè)
類似地,簡(jiǎn)單性假設(shè)原則是對(duì)簡(jiǎn)單這一價(jià)值觀的進(jìn)一步補(bǔ)充。這一原則要求開(kāi)發(fā)人員將每個(gè)問(wèn)題都看得十分容易解決,也就是說(shuō)只為本次迭代考慮,不去想未來(lái)可能需要什么,相信具有將來(lái)必要時(shí)增加系統(tǒng)復(fù)雜性的能力,也就是號(hào)召大家出色地完成今天的任務(wù)。
逐步修改
就像開(kāi)車打方向盤(pán)一樣,不要一次做出很大的改變,那樣將會(huì)使得可控性變差,更適合的方法是進(jìn)行微調(diào)。而在軟件開(kāi)發(fā)中,這樣的道理同樣適用,任何問(wèn)題都應(yīng)該通過(guò)一系列能夠帶來(lái)差異的微小改動(dòng)來(lái)解決。
提倡更改
在軟件開(kāi)發(fā)過(guò)程中,最好的辦法是在解決最重要問(wèn)題時(shí),保留最多選項(xiàng)的那個(gè)。也就是說(shuō),盡量為下一次修改做好準(zhǔn)備。
優(yōu)質(zhì)工作
在實(shí)踐中,經(jīng)常看到許多開(kāi)發(fā)人員喜歡將一些細(xì)小的問(wèn)題留待后面解決。例如,界面的按鈕有一些不平整,由于不影響使用就先不管;某一兩個(gè)成員函數(shù)暫時(shí)沒(méi)用就不先寫(xiě)等。這就是一種工作拖泥帶水的現(xiàn)象,這樣的壞習(xí)慣一旦養(yǎng)成,必然使得代碼質(zhì)量大打折扣。
而在 XP 方法論中,貫徹的是“小步快走”的開(kāi)發(fā)原則,因此工作質(zhì)量決不可打折扣,通常采用測(cè)試先行的編碼方式來(lái)提供支持。
13 個(gè)最佳實(shí)踐
在 XP 中,集成了 13 個(gè)最佳實(shí)踐,有趣的是,它們沒(méi)有一個(gè)是創(chuàng)新的概念,大多數(shù)概念和編程一樣老。其主要?jiǎng)?chuàng)新點(diǎn)在于提供一種良好的思路,將這些最佳實(shí)踐結(jié)合在一起,并且確保盡可能徹底地執(zhí)行它們,使得它們能夠在最大程度上相互支持,緊接下來(lái),我們就對(duì)每一種最佳實(shí)踐進(jìn)行一番了解。
計(jì)劃游戲
計(jì)劃游戲的主要思想就是先快速地制定一份概要的計(jì)劃,然后隨著項(xiàng)目細(xì)節(jié)的不斷清晰,再逐步完善這份計(jì)劃。計(jì)劃游戲產(chǎn)生的結(jié)果是一套用戶故事及后續(xù)的一兩次迭代的概要計(jì)劃。
“客戶負(fù)責(zé)業(yè)務(wù)決策,開(kāi)發(fā)團(tuán)隊(duì)負(fù)責(zé)技術(shù)決策”是計(jì)劃游戲獲得成功的前提條件。也就是說(shuō),系統(tǒng)的范圍、下一次迭代的發(fā)布時(shí)間、用戶故事的優(yōu)先級(jí)應(yīng)該由客戶決定;而每個(gè)用戶故事所需的開(kāi)發(fā)時(shí)間、不同技術(shù)的成本、如何組建團(tuán)隊(duì)、每個(gè)用戶故事的風(fēng)險(xiǎn),以及具體的開(kāi)發(fā)順序應(yīng)該由開(kāi)發(fā)團(tuán)隊(duì)決定。
好了,明白這些就可以進(jìn)行計(jì)劃游戲了。首先客戶和開(kāi)發(fā)人員坐在同一間屋子里,每個(gè)人都準(zhǔn)備一支筆、一些用于記錄用戶故事的紙片,最好再準(zhǔn)備一個(gè)白板,就可以開(kāi)始了。
- 客戶編寫(xiě)故事:由客戶談?wù)撓到y(tǒng)應(yīng)該完成什么功能,然后用通俗的自然語(yǔ)言,使用自己的語(yǔ)匯,將其寫(xiě)在卡片上,這也就是用戶故事。
- 開(kāi)發(fā)人員進(jìn)行估算:首先客戶按優(yōu)先級(jí)將用戶故事分成必須要有、希望有、如果有更好三類,然后開(kāi)發(fā)人員對(duì)每個(gè)用戶故事進(jìn)行估算,先從高優(yōu)先級(jí)開(kāi)始估算。如果在估算的時(shí)候,感到有一些故事太大,不容易進(jìn)行估算,或者是估算的結(jié)果超過(guò) 2人/周,那么就應(yīng)該對(duì)其進(jìn)行分解,拆成 2 個(gè)或者多個(gè)小故事。
- 確定迭代的周期:接下來(lái)就是確定本次迭代的時(shí)間周期,這可以根據(jù)實(shí)際的情況進(jìn)行確定,不過(guò)最佳的迭代周期是 2~3 周。有了迭代的時(shí)間之后,再結(jié)合參與的開(kāi)發(fā)人數(shù),算出可以完成的工作量總數(shù)。然后根據(jù)估算的結(jié)果,與客戶協(xié)商,挑出時(shí)間上夠、優(yōu)先級(jí)合適的用戶故事組合,形成計(jì)劃。
小型發(fā)布
XP 方法論秉承的是“持續(xù)集成,小步快走”的哲學(xué),也就是說(shuō)每一次發(fā)布的版本應(yīng)該盡可能的小,當(dāng)然前提條件是每個(gè)版本有足夠的商業(yè)價(jià)值,值得發(fā)布。
由于小型發(fā)布可以使得集成更頻繁,客戶獲得的中間結(jié)果也越頻繁,反饋也就越頻繁,客戶就能夠?qū)崟r(shí)地了解項(xiàng)目的進(jìn)展情況,從而提出更多的意見(jiàn),以便在下一次迭代中計(jì)劃進(jìn)去。以實(shí)現(xiàn)更高的客戶滿意度。
隱喻
相對(duì)而言,隱喻這一個(gè)最佳實(shí)踐是最令人費(fèi)解的。什么是隱喻呢?根據(jù)詞典中的解釋是:“一種語(yǔ)言的表達(dá)手段,它用來(lái)暗示字面意義不相似的事物之間的相似之處”。那么這在軟件開(kāi)發(fā)中又有什么用呢?總結(jié)而言,常常用于四個(gè)方面。
- 尋求共識(shí):也就是鼓勵(lì)開(kāi)發(fā)人員在尋求問(wèn)題共識(shí)時(shí),可以借用一些溝通雙方都比較熟悉的事物來(lái)做類比,從而幫助大家更好地理解解決方案的關(guān)鍵結(jié)構(gòu),也就是更好地理解系統(tǒng)是什么、能做什么。
- 發(fā)明共享詞匯:通過(guò)隱喻,有助于提出一個(gè)用來(lái)表示對(duì)象、對(duì)象間的關(guān)系通用名稱。例如,策略模式(用來(lái)表示可以實(shí)現(xiàn)多種不同策略的設(shè)計(jì)模式)、工廠模式(用來(lái)表示可以按需“生產(chǎn)”出所需類得設(shè)計(jì)模式)等。
- 創(chuàng)新的武器:有的時(shí)候,可以借助其他東西來(lái)找到解決問(wèn)題的新途徑。例如:“我們可以將工作流看做一個(gè)生產(chǎn)線”。
- 描述體系結(jié)構(gòu):體系結(jié)構(gòu)是比較抽象的,引入隱喻能夠大大減輕理解的復(fù)雜度。例如管道體系結(jié)構(gòu)就是指兩個(gè)構(gòu)件之間通過(guò)一條傳遞消息的“管道”進(jìn)行通信。
當(dāng)然,如果能夠找到合適的隱喻是十分快樂(lè)的,但并不是每種情況都可以找到恰當(dāng)?shù)碾[喻,你也沒(méi)有必要強(qiáng)求
簡(jiǎn)單設(shè)計(jì)
強(qiáng)調(diào)簡(jiǎn)單設(shè)計(jì)的價(jià)值觀,引出了簡(jiǎn)單性假設(shè)原則,落到實(shí)處就是“簡(jiǎn)單設(shè)計(jì)”實(shí)踐。這個(gè)實(shí)踐看上去似乎很容易理解,但卻又經(jīng)常被誤解,許多批評(píng)者就指責(zé) XP 忽略設(shè)計(jì)是不正確的。其實(shí),XP 的簡(jiǎn)單設(shè)計(jì)實(shí)踐并不是要忽略設(shè)計(jì),而且認(rèn)為設(shè)計(jì)不應(yīng)該在編碼之前一次性完成,因?yàn)槟菢又荒芙⒃凇扒闆r不會(huì)發(fā)生變化”或者“我們可以預(yù)見(jiàn)所有的變化”之類的謊言的基礎(chǔ)上的。
Kent Beck 概念中簡(jiǎn)單設(shè)計(jì)是這樣的:
- 能夠通過(guò)所有的測(cè)試程序。
- 沒(méi)有包括任何重復(fù)的代碼。
- 清楚地表現(xiàn)了程序員賦予的所有意圖。
- 包括盡可能少的類和方法
- 他認(rèn)為要想保持設(shè)計(jì)簡(jiǎn)單的系統(tǒng),需要具備簡(jiǎn)單思考的能力,擁有理解代碼和修改的勇氣,以及為了消除代碼的“壞味道”而定期重構(gòu)的習(xí)慣。
- 那么如何開(kāi)始進(jìn)行簡(jiǎn)單的設(shè)計(jì)呢?XP 實(shí)踐者們也總結(jié)也一些具體的、可操作的思考方法。
- 首先寫(xiě)測(cè)試代碼:具體將在后面詳細(xì)描述。
- 保持每個(gè)類只負(fù)責(zé)一件事:SRP(單一職責(zé)原則)是面向?qū)ο笤O(shè)計(jì)的基礎(chǔ)原則之一。
- 使用 Demeter(迪米特)法則:迪米特法則,也稱為 LoD 法則、最少知識(shí)原則。也就是指一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象盡可能少地了解。用隱喻的方法來(lái)解釋的話就是“只與你直接的朋友通信”、“不要和陌生人說(shuō)話”。
- 使用 CRC 卡片進(jìn)行探索。
測(cè)試先行/測(cè)試驅(qū)動(dòng)開(kāi)發(fā)
當(dāng)我第一次看到“測(cè)試先行”這個(gè)概念的時(shí)候,我的第一感覺(jué)就是不解,陷入了“程序都還沒(méi)有寫(xiě)出來(lái),測(cè)試什么呀?”的迷思。我開(kāi)始天馬行空地尋求相關(guān)的隱喻,終于找到了能夠啟發(fā)我的工匠,首先,我們來(lái)看看兩個(gè)不同的工匠是如何工作的吧。
- 工匠一:先拉上一根水平線,砌每一塊磚時(shí),都與這跟水平線進(jìn)行比較,使得每一塊磚都保持水平。
- 工匠二:先將一排磚都砌完,然后再拉上一根水平線,看看哪些磚有問(wèn)題,對(duì)有問(wèn)題的磚進(jìn)行適當(dāng)?shù)恼{(diào)整。
你會(huì)選擇哪種工作方法呢?你一定會(huì)罵工匠二笨吧!這樣多浪費(fèi)時(shí)間呀!然而你自己想想,你平時(shí)在編寫(xiě)程序的時(shí)候又是怎么做的呢?我們就是按工匠二的方法在工作呀!甚至有時(shí)候比工匠二還笨,是整面墻都砌完了,直接進(jìn)行“集成測(cè)試”,經(jīng)常讓整面的墻倒塌。看到這里,你還會(huì)覺(jué)得自己的方法高明嗎?這個(gè)連工匠都明白的道理,自己卻畫(huà)地為牢呀。
不僅我們沒(méi)有采用工匠一的工作方法,甚至有的時(shí)候程序員會(huì)以“開(kāi)發(fā)工作太緊張”為理由,而忽略測(cè)試工作。但這樣卻導(dǎo)致了一個(gè)惡性循環(huán),越是沒(méi)有空編寫(xiě)測(cè)試程序,代碼的效率與質(zhì)量越差,花在找 Bug、解決 Bug 的時(shí)間也越來(lái)越多,實(shí)際產(chǎn)能大打降低。由于產(chǎn)能降低了,因此時(shí)間更緊張,壓力更大。你想想,為什么不拉上一根水平線呢?難道,我們不能夠?qū)⒑竺胬速M(fèi)的時(shí)間花在單元測(cè)試上,使得我們的程序一開(kāi)始就更健壯,更加易于修改嗎?不過(guò),編寫(xiě)測(cè)試程序當(dāng)然要比拉一條水平線難道多,所以我們需要引入“自動(dòng)化測(cè)試工具”,免費(fèi)的 xUnit 測(cè)試框架就是你最佳的選擇。
為了鼓勵(lì)程序員原意甚至喜歡在編寫(xiě)程序之前編寫(xiě)測(cè)試代碼,XP 方法論還提供了許多有說(shuō)服力的理由。
- 如果你已經(jīng)保持了簡(jiǎn)單的設(shè)計(jì),那么編寫(xiě)測(cè)試代碼根本不難。
- 如果你在結(jié)對(duì)編程,那么如果你想出一個(gè)好的測(cè)試代碼,那么你的伙伴一定行。
- 當(dāng)所有的測(cè)試都通過(guò)的時(shí)候,你再也不會(huì)擔(dān)心所寫(xiě)的代碼今后會(huì)“暗箭傷人”,那種感覺(jué)是相當(dāng)棒的。
- 當(dāng)你的客戶看到所有的測(cè)試都通過(guò)的時(shí)候,會(huì)對(duì)程序充滿前所未有的信心。
- 當(dāng)你需要進(jìn)行重構(gòu)時(shí),測(cè)試代碼會(huì)給你帶來(lái)更大的勇氣,因?yàn)槟阋獪y(cè)試是否重構(gòu)成功只需要一個(gè)按鈕。
測(cè)試先行是 XP 方法論中一個(gè)十分重要的最佳實(shí)踐,并且其中所蘊(yùn)含的知識(shí)與方法也十分豐富。
重構(gòu)
重構(gòu)時(shí)一種對(duì)代碼進(jìn)行改進(jìn)而不影響功能實(shí)現(xiàn)的技術(shù),XP 需要開(kāi)發(fā)人員在聞到代碼的壞味道時(shí),有重構(gòu)代碼的勇氣。重構(gòu)的目的是降低變化引發(fā)的風(fēng)險(xiǎn),使得代碼優(yōu)化更加容易。通常重構(gòu)發(fā)生在兩種情況之下。
- 實(shí)現(xiàn)某個(gè)特性之前:嘗試改變現(xiàn)有的代碼結(jié)構(gòu),以使得實(shí)現(xiàn)新的特性更加容易。
- 實(shí)現(xiàn)某個(gè)特性之后:檢查剛剛寫(xiě)完的代碼后,認(rèn)真檢查一下,看是否能夠進(jìn)行簡(jiǎn)化。
在《重構(gòu)》一書(shū)中,作者 Martin Fowler 提示我們:在考慮重構(gòu)時(shí),應(yīng)該要養(yǎng)成編寫(xiě)并經(jīng)常運(yùn)行測(cè)試代碼的習(xí)慣;要先編寫(xiě)代碼,再進(jìn)行重構(gòu);把每一次增加功能都當(dāng)做一次重構(gòu)的好時(shí)機(jī);將每一個(gè)糾正錯(cuò)誤當(dāng)做一次重構(gòu)的重要時(shí)機(jī)。同時(shí),該書(shū)中也列出大量需要重構(gòu)的情況和重構(gòu)方法。
最后類似地,給還沒(méi)有足夠勇氣進(jìn)行重構(gòu)的程序員打幾劑強(qiáng)心針:
- XP 提倡集體代碼所有制,因此你可以大膽地在任何需要修改的地方做改動(dòng)。
- 由于在 XP 項(xiàng)目組中有完整的編碼標(biāo)準(zhǔn),因此在重構(gòu)前無(wú)須重新定義格式。
- 在重構(gòu)中遇到困難,和你結(jié)對(duì)編程的伙伴能夠?yàn)槟闾峁┯行У膸椭?/li>
- 簡(jiǎn)單的設(shè)計(jì),會(huì)給重構(gòu)帶來(lái)很大的幫助。
- 測(cè)試先行讓你擁有了一個(gè)有效的檢驗(yàn)器,隨時(shí)運(yùn)行一下就知道你重構(gòu)的工作是否帶來(lái)了影響。
- 由于 XP 在持續(xù)集成,因此你重構(gòu)所帶來(lái)的破壞很快就能夠暴露,并且得以解決。
重構(gòu)技術(shù)是對(duì)簡(jiǎn)單性設(shè)計(jì)的一個(gè)良好的補(bǔ)充,也是 XP 中重視“優(yōu)質(zhì)工作”的體現(xiàn),這也是優(yōu)秀的程序員必備的一項(xiàng)技能。
結(jié)對(duì)編程
“什么!兩個(gè)人坐在一起寫(xiě)程序?那豈不是對(duì)人力的巨大浪費(fèi)嗎?而且我在工作時(shí)可不喜歡有一個(gè)人坐在邊上當(dāng)檢察官。”是的,正如這里列舉出來(lái)的問(wèn)題一樣,結(jié)對(duì)編程技術(shù)還是被很多人質(zhì)疑的。
不過(guò),自從 20 世紀(jì) 60 年代,就有類似的實(shí)踐在進(jìn)行,長(zhǎng)期以來(lái)的研究結(jié)果卻給出了另外一番景象,那就是結(jié)對(duì)編程的效率反而比單獨(dú)編程更高。一開(kāi)始雖然會(huì)犧牲一些速度,但慢慢的,開(kāi)發(fā)速度會(huì)逐漸加快,究其原因,主要是結(jié)對(duì)編程大打降低了溝通的成本,提供了工作的質(zhì)量,具體表現(xiàn)在:
- 所有的設(shè)計(jì)決策確保不是由一個(gè)人做出的。
- 系統(tǒng)的任何一個(gè)部分都肯定至少有 2 個(gè)人以上熟悉。
- 幾乎不可能有 2 個(gè)人都忽略的測(cè)試項(xiàng)或者其他任務(wù)
- 結(jié)對(duì)組合的動(dòng)態(tài)性,是一個(gè)企業(yè)知識(shí)管理的好途徑。
- 代碼總是能夠保證被評(píng)審過(guò)。
- 而且 XP 方法論集成的其他最佳實(shí)踐也能夠使得結(jié)對(duì)編程更加容易進(jìn)行:
- 編碼標(biāo)準(zhǔn)可以消除一些無(wú)謂的分歧。
- 隱喻可以幫助結(jié)對(duì)伙伴更好地溝通。
- 簡(jiǎn)單設(shè)計(jì)可以使得結(jié)對(duì)伙伴更了解他們所從事的工作。
結(jié)對(duì)編程技術(shù)被譽(yù)為 XP 保持工作質(zhì)量、強(qiáng)調(diào)人文主義的一個(gè)典型的實(shí)踐,應(yīng)用得當(dāng)還能夠使得開(kāi)發(fā)團(tuán)隊(duì)之前的協(xié)作更加流暢、知識(shí)交流與共享更加頻繁,團(tuán)隊(duì)的穩(wěn)定性也會(huì)更加穩(wěn)固。
集體代碼所有制
由于 XP 方法論鼓勵(lì)團(tuán)隊(duì)進(jìn)行結(jié)對(duì)編程,而且認(rèn)為結(jié)對(duì)編程的組合應(yīng)該動(dòng)態(tài)地搭配,根據(jù)任務(wù)的不同、專業(yè)技能的不同進(jìn)行最優(yōu)組合。由于每個(gè)人都肯定會(huì)遇到不同的代碼,所以代碼的所有制就不再適合于私有,因?yàn)槟菢訒?huì)給修改工作帶來(lái)巨大的不便。
也就是說(shuō),團(tuán)隊(duì)中的每個(gè)成員都擁有對(duì)代碼進(jìn)行改進(jìn)的權(quán)利,每個(gè)人都擁有全部代碼,也都需要對(duì)全部代碼負(fù)責(zé)。同時(shí),XP 強(qiáng)調(diào)代碼是誰(shuí)破壞的(也就是修改后發(fā)生問(wèn)題),就應(yīng)該由誰(shuí)來(lái)修復(fù)。
由于在 XP 中,有一些與之匹配的最佳實(shí)踐,因此你并無(wú)須擔(dān)心采用集體代碼所有制會(huì)讓你的代碼變得越來(lái)越亂:
- 由于在 XP 項(xiàng)目中,集成工作是一件經(jīng)常性得工作,因此當(dāng)有人修改代碼而帶來(lái)了集成的問(wèn)題,會(huì)在很快的時(shí)間內(nèi)被發(fā)現(xiàn)。
- 由于每一個(gè)類都會(huì)有一個(gè)測(cè)試代碼,因此不論誰(shuí)修改了代碼,都需要運(yùn)行這個(gè)測(cè)試代碼,這樣偶然性的破壞發(fā)生的概率將很小。
- 由于每一個(gè)代碼的修改就是通過(guò)了結(jié)對(duì)的兩個(gè)程序員共同思考,因此通常做出的修改都是對(duì)系統(tǒng)有益的。
- 由于大家都堅(jiān)持了相同的編碼標(biāo)準(zhǔn),因此代碼的可讀性、可修改性都會(huì)比較好,而且還能夠避免由于命名法、縮進(jìn)等小問(wèn)題引發(fā)經(jīng)常性得代碼修改。
集成代碼所有制是 XP 與其他敏捷方法的一個(gè)較大不同,也是從另一個(gè)側(cè)面體現(xiàn)了 XP 中蘊(yùn)含的很深厚的編碼情節(jié)。
持續(xù)集成
在前面談到小型發(fā)布、重構(gòu)、結(jié)對(duì)編程、集體代碼所有制等最佳實(shí)踐的時(shí)候,我們多次看到“持續(xù)集成”的身影,可以說(shuō)持續(xù)集成是對(duì)這些最佳實(shí)踐的基本支撐條件。
可能大家會(huì)對(duì)持續(xù)集成與小型發(fā)布代表的意思混淆不清,其實(shí)小型發(fā)布是指在開(kāi)發(fā)周期經(jīng)常發(fā)布中間版本,而持續(xù)集成的含義則是要求 XP 團(tuán)隊(duì)每天盡可能多次地做代碼集成,每次都在確保系統(tǒng)運(yùn)行的單元測(cè)試通過(guò)之后進(jìn)行。
這樣,就可以及早地暴露、消除由于重構(gòu)、集體代碼所有制所引入的錯(cuò)誤,從而減少解決問(wèn)題的痛苦
要在開(kāi)發(fā)過(guò)程中做到持續(xù)集成并不容易,首先需要養(yǎng)成這個(gè)習(xí)慣。而且集成工作往往是十分枯燥、煩瑣的,因此適當(dāng)?shù)匾朊咳占晒ぞ呤鞘直匾摹P 建議大家首先使用配置管理服務(wù)器將代碼管理起來(lái),然后使用 Ant 或 Nant 等 XP 工具,編寫(xiě)集成腳本,調(diào)用 xUint 等測(cè)試框架,這樣就可以實(shí)現(xiàn)每當(dāng)程序員將代碼 Check in 到配置服務(wù)器上時(shí),Ant 就會(huì)自動(dòng)完成編譯和集成,并調(diào)用測(cè)試代碼完成相應(yīng)的測(cè)試工作。
每周工作 40 小時(shí)/可持續(xù)的速度
這是最讓開(kāi)發(fā)人員開(kāi)心的、管理者反對(duì)的一個(gè)最佳實(shí)踐了,加班、再加班早已成為開(kāi)發(fā)人員的家常便飯,也是管理者最常使用的一種策略,而 XP 方法論認(rèn)為,加班最終會(huì)扼殺團(tuán)隊(duì)的積極性,最終導(dǎo)致項(xiàng)目失敗,這也充分體現(xiàn)了 XP 方法關(guān)注人的因素比關(guān)注過(guò)程的因素更多一些。
Kent Beck 認(rèn)為開(kāi)發(fā)人員即使能夠工作更長(zhǎng)的時(shí)間,他們也不該這樣做,因?yàn)檫@樣做會(huì)使他們更容易厭倦編程工作,從而產(chǎn)生一些影響他們效能的其他問(wèn)題。因此,每周工作 40 小時(shí)是一種順勢(shì)行為,是一種規(guī)律。其實(shí)對(duì)于開(kāi)發(fā)人員和管理者來(lái)說(shuō),違反這種規(guī)律是不值得的。
- 開(kāi)發(fā)人員:如果不懂得休息,那么就無(wú)法將自己的節(jié)奏調(diào)整到最佳狀態(tài),那么就會(huì)帶來(lái)很大的負(fù)面影響。而且在精神不集中的狀態(tài)下,開(kāi)發(fā)質(zhì)量也得不到保證。
- 管理者:也許這可以稱得上“第二種人月神話”,那就是你不得不通過(guò)延長(zhǎng)每天的工作時(shí)間來(lái)獲得更多的人月。這是因?yàn)椋總€(gè)開(kāi)發(fā)人員的工作精力是有限的,不可能無(wú)限增長(zhǎng),在精力不足的時(shí)候,不僅寫(xiě)出來(lái)的代碼質(zhì)量沒(méi)有保障,而且還可能為項(xiàng)目帶來(lái)退步的效果。因此采用加班的方式并不是一個(gè)理性的方式,是得不償失的。
不過(guò)有一點(diǎn)是需要解釋的,“每周工作 40 小時(shí)”中的 40 不是一個(gè)絕對(duì)數(shù),它所代表的意思是團(tuán)隊(duì)?wèi)?yīng)該保證按照“正常的時(shí)間”進(jìn)行工作。那么如何做到這一點(diǎn)呢?
- 首先,定義符合你團(tuán)隊(duì)情況的“正常工作時(shí)間”。
- 其次,逐步將工作時(shí)間調(diào)整到“正常工作時(shí)間”。
- 再次,除非你的時(shí)間計(jì)劃一團(tuán)糟,否則不應(yīng)該在時(shí)間妥協(xié)。
- 最后,鼓起勇氣,制定一個(gè)合情合理的時(shí)間表。
正如米盧說(shuō)過(guò)的“享受足球”一樣,同樣地,每一個(gè)開(kāi)發(fā)人員應(yīng)該做到“享受編程”,那么“每周工作 40 小時(shí)”就是你的起點(diǎn)。
團(tuán)隊(duì)只有持久才有獲勝的希望。他們以能夠長(zhǎng)期維持的速度努力工作,他們保存精力,他們把項(xiàng)目看作是馬拉松長(zhǎng)跑,而不是全速短跑。
現(xiàn)場(chǎng)客戶
為了保證開(kāi)發(fā)出來(lái)的結(jié)果與客戶的預(yù)想接近,XP 方法論認(rèn)為最重要的需要將客戶請(qǐng)到開(kāi)發(fā)現(xiàn)場(chǎng)。就像計(jì)劃游戲中提到過(guò)的,在 XP 項(xiàng)目中,應(yīng)該時(shí)刻保證客戶負(fù)責(zé)業(yè)務(wù)決策,開(kāi)發(fā)團(tuán)隊(duì)負(fù)責(zé)技術(shù)決策。因此,在項(xiàng)目中有客戶在現(xiàn)場(chǎng)明確用戶故事,并做出相應(yīng)的業(yè)務(wù)決策,對(duì)于 XP 項(xiàng)目而言有著十分重要的意義。
也許有人會(huì)問(wèn),客戶提交了用戶故事之后不就完成工作了嗎?其實(shí)很多嘗試過(guò)用戶故事的團(tuán)隊(duì)都會(huì)發(fā)現(xiàn)其太過(guò)簡(jiǎn)單,包含的信息量極少,XP方法論不會(huì)不了解,因此,不會(huì)把用戶故事當(dāng)做開(kāi)發(fā)人員交付代碼的唯一指示。用戶故事只是一個(gè)起點(diǎn),后面的細(xì)節(jié)還需要開(kāi)發(fā)人員與客戶之間建立起來(lái)的良好溝通來(lái)補(bǔ)充。
作為一名有經(jīng)驗(yàn)的開(kāi)發(fā)人員,絕對(duì)不會(huì)對(duì)現(xiàn)場(chǎng)客戶的價(jià)值產(chǎn)生任何懷疑,但是都會(huì)覺(jué)得想要實(shí)現(xiàn)現(xiàn)場(chǎng)客戶十分困難。要實(shí)現(xiàn)這一點(diǎn),需要對(duì)客戶進(jìn)行溝通,讓其明白,想對(duì)于開(kāi)發(fā)團(tuán)隊(duì),項(xiàng)目成功對(duì)于客戶而言更為重要。而現(xiàn)場(chǎng)客戶則是保障項(xiàng)目成功的一個(gè)重要措施,想想在你裝修房子的時(shí)候,你是不是常常在充當(dāng)現(xiàn)場(chǎng)客戶的角色呢?其實(shí)這隱喻就是讓客戶理解現(xiàn)場(chǎng)客戶重要性最好的突破口。
其實(shí)現(xiàn)場(chǎng)客戶在具體實(shí)施時(shí),也不是一定需要客戶一直和開(kāi)發(fā)團(tuán)隊(duì)在一起,而是在開(kāi)發(fā)團(tuán)隊(duì)?wèi)?yīng)該和客戶能夠隨時(shí)溝通,可以是面談,可以是在線聊天,可以是電話,當(dāng)然面談是必不可少的。其中的關(guān)鍵是當(dāng)開(kāi)發(fā)人員需要客戶做出業(yè)務(wù)決策是,需要進(jìn)一步了解業(yè)務(wù)細(xì)節(jié)時(shí)能夠隨時(shí)找到相應(yīng)的客戶。
不過(guò),也有一些項(xiàng)目是可以不要現(xiàn)場(chǎng)客戶參與的:
- 當(dāng)開(kāi)發(fā)組織中已經(jīng)有相關(guān)的領(lǐng)域?qū)<視r(shí)。
- 當(dāng)做一些探索性工作,而且客戶也不知道他想要什么時(shí)(例如新產(chǎn)品、新解決方案的研究與開(kāi)發(fā))。
去嘗試吧,現(xiàn)場(chǎng)客戶不僅可以爭(zhēng)取得到,而且還能使得團(tuán)隊(duì)煥然一新,與客戶建立起良好的合作與信任。
編碼標(biāo)準(zhǔn)
編碼標(biāo)準(zhǔn)是一個(gè)“雅俗共享”的最佳實(shí)踐,不管是代表重型方法論的 RUP,PSP,還是代表敏捷方法論的 XP,都認(rèn)為開(kāi)發(fā)團(tuán)隊(duì)?wèi)?yīng)該擁有一個(gè)編碼標(biāo)準(zhǔn)。XP 方法論認(rèn)為擁有編碼標(biāo)準(zhǔn)可以避免團(tuán)隊(duì)在一些與開(kāi)發(fā)進(jìn)度無(wú)關(guān)的細(xì)節(jié)問(wèn)題上發(fā)生爭(zhēng)論,而且會(huì)給重構(gòu)、結(jié)對(duì)編程帶來(lái)很大麻煩。試想如果有人將你上次寫(xiě)的代碼的變量命名法做了修改,下次你需要再改這部分代碼時(shí),會(huì)是一種什么感覺(jué)呢?
不過(guò),XP 方法論的編碼標(biāo)準(zhǔn)的目的不是創(chuàng)建一個(gè)事無(wú)巨細(xì)的規(guī)則表,而是只要能夠提供一個(gè)確保代碼清晰,便于交流的指導(dǎo)方針。
如果你的團(tuán)隊(duì)已經(jīng)擁有編碼標(biāo)準(zhǔn),就可以直接使用它,并在過(guò)程中進(jìn)行完善。如果還沒(méi)有,那么大家可以先進(jìn)行編碼,然后在過(guò)程中逐步總結(jié)出編碼規(guī)則,邊做邊形成。當(dāng)然除了這種文字規(guī)范以外,還可以采用一些如自動(dòng)格式化代碼工具之類的方法進(jìn)行代碼規(guī)范。,事實(shí)上,你只需要很好地貫徹執(zhí)行其他的實(shí)踐并且進(jìn)行溝通,編碼標(biāo)準(zhǔn)會(huì)很容易地浮現(xiàn)出來(lái)。
配合是關(guān)鍵
有句經(jīng)典名言“1+1 > 2 ”最適合表達(dá) XP 的觀點(diǎn),Kent Beck 認(rèn)為 XP 方法論的最大價(jià)值在于在項(xiàng)目中融會(huì)貫通地運(yùn)用12個(gè)最佳實(shí)踐,而非單獨(dú)地使用。你當(dāng)然可以使用其中的一些實(shí)踐,但這并不意味著你就運(yùn)用了 XP 方法論。XP 方法論真正能夠發(fā)揮其效能,就必須完整地運(yùn)用12個(gè)實(shí)踐。