提到 XP 的關(guān)鍵實(shí)踐,就不得不拿出下面這張圖。
看著眼熟不?是不是很多內(nèi)容我們在上篇文章中其實(shí)都已經(jīng)講過了。沒錯,可能有些概念你很清楚,但有些概念你就完全沒聽說過了。今天,我們就來一次性地好好學(xué)習(xí)一下。
看到圖中的每一環(huán)了嗎?最里面的是編程方法相關(guān)的,中間的是小組實(shí)踐相關(guān)的,最外面的是交付和管理相關(guān)的,我們就從內(nèi)到外逐一學(xué)習(xí)。
一提到結(jié)對編程,估計(jì)寫代碼的人都會很感興趣。但是轉(zhuǎn)念一想:倆人一臺電腦,一個寫一個看,這個畫風(fēng)是不是有點(diǎn)兒曖昧...咳,這個如果是寫代碼還好,要是看一些別的什么不好的東西就真的很容易出事了,畢竟我們碼農(nóng)的口味是不好拿捏的。好吧,說正事,兩個人一起寫一份代碼,感覺是很大的浪費(fèi)呀!確實(shí),也有很多人質(zhì)疑,而且你在國內(nèi)不管大小公司,很少能見到真正地實(shí)現(xiàn)結(jié)對編程的公司。為什么呢?主要就是因?yàn)檫@種做法不太適合我們現(xiàn)在越來越卷的國內(nèi)的互聯(lián)網(wǎng)行業(yè),畢竟我們是需要通過不停地加班 996 來實(shí)現(xiàn)一個人當(dāng)兩個人用的,怎么可能讓兩個人去干一件事,這明顯違背老板的價(jià)值觀呀。
不過,敏捷實(shí)踐者們既然提出了這個做法,那么也一定是有它的可取之處的。比如:
所有的決定都不是一個人做出的
至少有兩個人熟悉系統(tǒng)的每一部分
幾乎不可能有 2 個人都忽視的測試或其它任務(wù)
改變組合對象(也就是換不同的人結(jié)對)可以讓知識在組織內(nèi)更好地傳播
代碼總在被審查
結(jié)對編程的效率比單獨(dú)編程更高
其它還有一些優(yōu)點(diǎn)就不一一列舉了。咋眼一看,貌似還不錯呀,不過就像前面所說的,在國內(nèi),或許有一些極限編程愛好者開的公司會用到,但大部分公司,或者說 99% 的公司中你都見不到。
想必這個對各位碼農(nóng)來說也不陌生吧,從我們寫代碼的角度來說,就是先寫測試再寫代碼,然后讓我們的代碼通過測試之后才算是完成開發(fā)。典型的框架就是各種單元測試框架,什么 JUnit、PHPUnit 之類的。這個吧,說實(shí)話,我這些年的開發(fā)之路上,也沒用到過。為什么呢?還是一點(diǎn),效率略低。不過,這種開發(fā)方式最后做出來的產(chǎn)品的質(zhì)量的確是沒話說的。
當(dāng)然,要使用 TDD 也是有前提的,第一當(dāng)然是領(lǐng)導(dǎo)和團(tuán)隊(duì)的支持,第二就是團(tuán)隊(duì)的編碼規(guī)范完善,第三就是整體水平還不能太次。因?yàn)槿绻阋婚_始就把測試寫錯了,那么寫出來的代碼也不可能對。另外,如果濫用這些單元測試的話,還會讓人走向極端,追求完美的 100% 的測試覆蓋率,這也是不可取的。大部分情況下,從 60 分到 80 分,我們可能付出 100 分的努力就可以達(dá)到,而從 80 分到 95 分,可能需要付出 500 分的努力。但是從 95 分到 99 分,可能就需要 100000 分的努力,而 99 到 100 ,則有可能是 10 的 N 次方的努力了。當(dāng)我們陷入到這種情況的時(shí)候,往往就會得不償失。
TDD 最核心的是去測什么東西呢?在 單元測試 階段,最需要測的是核心的算法,比如電商項(xiàng)目中的折扣金額之類的計(jì)算,返點(diǎn)優(yōu)惠的計(jì)算等。在代碼架構(gòu)中,這些往往是服務(wù)層要解決的問題,所以,我們主要測試的目標(biāo)應(yīng)該是服務(wù)層的代碼。
再從分層架構(gòu)上來說,控制層分發(fā)請求,接收參數(shù),做好效驗(yàn)方面的測試即可。模型層處理數(shù)據(jù)持久化,一定要注意入庫數(shù)據(jù)的安全性和完整性,做好這方面的測試即可。而服務(wù)層,也就是我們公共的計(jì)算部分,承擔(dān)著整個系統(tǒng)的核心,這些才是單元測試真正需要關(guān)心的地方。因此,和上方的結(jié)論一致,我們最重要的測試內(nèi)容就是服務(wù)層的核心算法或核心邏輯。
當(dāng)然,你也可以在控制層寫服務(wù),也可以在模型層寫服務(wù),總之,找出關(guān)鍵核心的處理業(yè)務(wù)邏輯和算法的地方,加強(qiáng)這個地方的測試覆蓋率,不要盲目的以整體的測試覆蓋率為標(biāo)準(zhǔn),這才是 TDD 能夠更好運(yùn)用的重要方面。
理論歸理論,這方面其實(shí)我并沒有太多的實(shí)戰(zhàn)經(jīng)驗(yàn),不過我也覺得測試覆蓋率不能說明一切,在這里更希望有經(jīng)驗(yàn)的同學(xué)能夠分享相關(guān)的經(jīng)驗(yàn),可以評論里留鏈接或者加好友轉(zhuǎn)載文章哦!
這個詞對于寫代碼的人來說就更不陌生了,甚至很多人在換到新的公司時(shí),第一個建議就是咱們重構(gòu)一下老項(xiàng)目的代碼吧,因?yàn)榍叭藢懙锰玐了。當(dāng)然,想法總是好的,但現(xiàn)實(shí)其實(shí)是很殘酷的,真正的重構(gòu)不是說我們要讓所有的代碼都變成你喜歡的代碼。真正的重構(gòu)是源于敏捷的不斷迭代的重構(gòu)。在收下兩種情況下,我們通常會開始重構(gòu)一段代碼。
實(shí)現(xiàn)某個特性之前:嘗試改變現(xiàn)有的代碼結(jié)構(gòu),以使得實(shí)現(xiàn)新的特性更加容易
實(shí)現(xiàn)特性之后:檢查剛剛寫完的代碼后,看是否能夠進(jìn)一步的優(yōu)化
在重構(gòu)中,有一個重要的概念就是 Don't Repect Your Self 也就是非常出名的 DRY 原則。從開發(fā)的角度來說,就是不要讓一段相同的代碼出現(xiàn)兩次。另外,重構(gòu)還和 XP 中的其它元素緊密相關(guān),比如說代碼集體所有制,讓代碼共享所有人都能看到代碼,并且通過結(jié)對編程,你的重構(gòu)也會被別人發(fā)現(xiàn)并指出優(yōu)劣。需要完善的測試驅(qū)動開發(fā)機(jī)制,這樣才能確保你的重構(gòu)不會帶來問題。簡單的設(shè)計(jì),會讓你在重構(gòu)的過程中關(guān)注最核心的部分,寫出能夠?qū)崿F(xiàn)功能的最簡單的代碼。
通過上述內(nèi)容,其實(shí)我們也就保證了 XP 中 勇氣 的含義,讓你能夠勇敢的去重構(gòu)。
還記得 XP 核心思想中的 簡單 原則嗎?沒錯,設(shè)計(jì)是很重要,但是,我們應(yīng)該從最簡單的設(shè)計(jì)開始,通過迭代和增量不斷地完善它,而不是一開始就做出一個復(fù)雜的設(shè)計(jì)來。對于簡單來說,并不是說所有的設(shè)計(jì)都很小,只是說我們需要的是盡可能簡單的設(shè)計(jì)它,讓它盡快跑起來,通過持續(xù)發(fā)布來不斷驗(yàn)證和完善。
之前聽說過一個故事,也是程序員間的笑話。一個公司上來就是各種高精尖的技術(shù),各種高并發(fā)的處理,引入了一大堆阿里、騰訊的功能架構(gòu)實(shí)踐。結(jié)果呢?每日最高只有可憐的幾百日活。而這個項(xiàng)目做了多久呢?幾百人的開發(fā)團(tuán)隊(duì),一年的開發(fā)時(shí)間,最后不了了之。
還好,目前大部分公司都不會再干這種事。甚至很多公司都會以 MVP(最小可行版本) 的形式來進(jìn)行新項(xiàng)目的開發(fā)。這是好事,也是值得提倡的。那么,在 XP 中,對于簡單設(shè)計(jì)有什么建議嗎?
編寫測試代碼
保持每個類只負(fù)責(zé)一件事(單一職責(zé)原則)
迪米特法則(最少知識原則)
DRY 原則
簡單的設(shè)計(jì)需要簡單的思考,要有勇于重構(gòu)的勇氣和定期重構(gòu)的習(xí)慣
持續(xù)集成也是我們碼農(nóng)們經(jīng)常聽到的一個名詞,甚至不少人也使用并實(shí)踐過 Jenkins 、Travis CI 這類的持續(xù)集成工具。但是你知道嗎?這些工具的誕生也正是因?yàn)槭艿?XP 的影響。
持續(xù)集成的關(guān)鍵點(diǎn)是什么?不斷的編譯整合代碼,在你將代碼提交到 Git 的時(shí)候,測試環(huán)境就開始進(jìn)行單元測試,如果沒有通過,那么會報(bào)出異常,如果通過了,就會直接打包代碼。這樣就可以使代碼隨時(shí)保持在可以發(fā)布的狀態(tài)。因此,隨時(shí)整合,越頻繁越好,集成及測試過程的自動化程度越高越好,這就是持續(xù)集成的根本概念。
一般在自營業(yè)務(wù)的公司,都會有一個固定的代碼上線時(shí)間,快一點(diǎn)的可能是每周一次。而持續(xù)集成期望達(dá)到的最低標(biāo)準(zhǔn)是每日集成,也就是每日都能讓代碼進(jìn)行上線。當(dāng)然,依托現(xiàn)代化的這些持續(xù)集成工具,其實(shí)我們真的可以做到隨時(shí)提交隨時(shí)集成并上線。
初看 隱喻 這個詞感覺很神秘呀,這個玩意是什么意思呢?比較官方的解釋是 “隱喻是一種語言表達(dá)手段,它用來暗示字面意義不相似的事物之間的相似之處”,用俗語來說,就是將設(shè)計(jì)模型、開發(fā)模式這些關(guān)鍵概念抽象化為一些比喻。就像一個經(jīng)典的說法,你能給一個完全不懂軟件開發(fā)的人講明白數(shù)據(jù)庫是干什么的一樣,在這其中,相信你也會使用很多的比喻。比如說,數(shù)據(jù)庫就是一個書店,我們要從這個書店中一個個的書架上找到想要書的,等等等。
在 XP 中,隱喻的作用主要是加強(qiáng)客戶和程序員之間的相互理解,消化積累知識,指導(dǎo)設(shè)計(jì)的開發(fā)方向。具體來說,它可以幫助我們:
尋求共識
發(fā)明共享詞匯(屬于我們團(tuán)隊(duì)與客戶交流的詞典)
創(chuàng)新的重要手段(有時(shí)候恰當(dāng)?shù)谋扔髂軌蚣ぐl(fā)更多的靈感)
描述體系結(jié)構(gòu)(讓抽象的概念更加好理解)
今天的內(nèi)容多嗎?還好吧,因?yàn)槲覀兊?XP 關(guān)鍵實(shí)踐有 13 個呢,后面還有一篇文章要繼續(xù)學(xué)習(xí)的。不知道大家發(fā)現(xiàn)沒有,XP 的實(shí)踐完全是和軟件開發(fā)密切相關(guān)的,這也沒辦法,畢竟 Kent Back 本身就是一名軟件大師。你知道嗎?設(shè)計(jì)模式實(shí)踐的先行者、《重構(gòu)》作者 Martin Fowler 的好友同時(shí)也為這本書提供了不少內(nèi)容、XP 和 TDD(JUnit) 的創(chuàng)始人,這一堆名頭說的都是他。大家別急,下篇文章我們將繼續(xù)膜拜大師的作品,繼續(xù)我們的 XP 之路。
參考文檔:
《某培訓(xùn)機(jī)構(gòu)教材》
《用戶故事與敏捷方法》
《高效通過PMI-ACP考試(第2版)》
《敏捷項(xiàng)目管理與PMI-ACP應(yīng)試指南》
、