架構(gòu)之重構(gòu)的十二條軍規(guī)
對(duì)于開(kāi)發(fā)者來(lái)說(shuō),架構(gòu)設(shè)計(jì)是軟件研發(fā)過(guò)程中最重要的一環(huán),所謂沒(méi)有圖紙,就建不了房子。在遍地App的互聯(lián)網(wǎng)時(shí)代,架構(gòu)設(shè)計(jì)有了一些比較成熟的模式,開(kāi)發(fā)者和架構(gòu)師也可以經(jīng)常借鑒。
但是,隨著應(yīng)用的不斷發(fā)展,最初的架構(gòu)往往面臨著各種問(wèn)題,比如無(wú)法滿足客戶的需求、無(wú)法實(shí)現(xiàn)應(yīng)用的擴(kuò)展、無(wú)法實(shí)現(xiàn)新的特性等等。在這種情況下,我們?nèi)绾伪苊庖恍┛樱M量比較成功地實(shí)現(xiàn)架構(gòu)的重構(gòu),是很多開(kāi)發(fā)者和架構(gòu)師亟需解決的問(wèn)題。
在這里,跟大家分享一下Uber的工程主管Raffi Krikorian的12條規(guī)則,并附上一些解讀,希望對(duì)大家有所啟發(fā)。
確定重構(gòu)的目的和必要性
看起來(lái)這個(gè)規(guī)矩有些多余,但是請(qǐng)不要忽略。每一次架構(gòu)的重構(gòu)都是“傷筋動(dòng)骨”,就像做手術(shù)一樣,即使再成功,也會(huì)傷元?dú)?,所以決策者們首先要分析架構(gòu)重構(gòu)的理由和其他備選方案,明確重構(gòu)的目的是為了滿足業(yè)務(wù)需求,并且是不得不做的最佳方案,然后再考慮其他問(wèn)題。有時(shí)候,經(jīng)過(guò)分析就會(huì)發(fā)現(xiàn),也許還有其他解決方案,比如增加計(jì)算資源,或者重構(gòu)的目的不是為了業(yè)務(wù)需求,那就沒(méi)有必要做了。
檢查清單:
- 架構(gòu)重構(gòu)的原因是什么,是為了滿足業(yè)務(wù)的需要還是只是覺(jué)得架構(gòu)不好看?
- 除了架構(gòu)重構(gòu)之外,還有其他備選方案嗎?是否都分析過(guò)這些方案的利弊?
定義“重構(gòu)完成”的界限
如果確定要重構(gòu),那么要把目標(biāo)明確下來(lái),也就是重構(gòu)的邊界條件,怎么才算是“完成”了重構(gòu),目標(biāo)要有數(shù)據(jù)量化,或者有能夠測(cè)試的辦法。這也是一個(gè)需求分析的過(guò)程,如果需求不明確,那么規(guī)格說(shuō)明書沒(méi)法寫清楚,負(fù)責(zé)重構(gòu)的團(tuán)隊(duì)也沒(méi)有明確的目標(biāo),不能以重構(gòu)的時(shí)間或者主觀的判斷為結(jié)束的依據(jù)。前幾天和一朋友聊天,他最近在負(fù)責(zé)系統(tǒng)的性能優(yōu)化,也要做一些重構(gòu)的事情,開(kāi)始的時(shí)候團(tuán)隊(duì)的目標(biāo)不明確,大家不知道優(yōu)化到什么程度,所以不敢下手。如果目標(biāo)是提高10%,那么可以從細(xì)節(jié)處著手;如果是提高50%,那可能要搞大動(dòng)作才能實(shí)現(xiàn)了。后來(lái)目標(biāo)明確之后,團(tuán)隊(duì)才找到合適的辦法。
檢查清單:
- 重構(gòu)的目標(biāo)可以量化,或者說(shuō)可以測(cè)試嗎?
- 重構(gòu)完成的標(biāo)準(zhǔn)是什么?得到業(yè)務(wù)部門或者領(lǐng)導(dǎo)的認(rèn)可了嗎?
漸進(jìn)式重構(gòu)
現(xiàn)在軟件研發(fā)最流行的就是快速迭代、持續(xù)交付、盡早反饋。這同樣可以用在架構(gòu)的重構(gòu)上,重構(gòu)過(guò)程的難度不亞于構(gòu)建一個(gè)新產(chǎn)品,所以在設(shè)計(jì)重構(gòu)的時(shí)候,要引入持續(xù)交付的流程,每一個(gè)重構(gòu)步驟或者模塊都要快速部署并得到反饋,以便評(píng)估重構(gòu)的效果,及時(shí)作出策略調(diào)整。有的讀者會(huì)說(shuō),我們的架構(gòu)重構(gòu)是釜底抽薪型的,沒(méi)法漸進(jìn),只能一蹴而就。如果是這種情況,可以考慮在另外一套拷貝的系統(tǒng)中做重構(gòu),經(jīng)過(guò)謹(jǐn)慎測(cè)試之后,將數(shù)據(jù)和業(yè)務(wù)遷移過(guò)去。
檢查清單:
- 能否把重構(gòu)過(guò)程分成小的迭代,每一次改進(jìn)都能盡快得到反饋?
- 重構(gòu)過(guò)程中的效果能夠定期展示給業(yè)務(wù)部門或者領(lǐng)導(dǎo)嗎?
確定當(dāng)前的架構(gòu)狀態(tài)
在啟動(dòng)重構(gòu)之前,團(tuán)隊(duì)要對(duì)當(dāng)前的架構(gòu)狀態(tài)有清晰的了解,也就是設(shè)定好基準(zhǔn),以便評(píng)估重構(gòu)的效果。據(jù)我的經(jīng)驗(yàn),負(fù)責(zé)重構(gòu)的架構(gòu)師或者開(kāi)發(fā)者,往往還沒(méi)有搞清楚現(xiàn)有的架構(gòu)設(shè)計(jì),就開(kāi)始重構(gòu)了,結(jié)果經(jīng)常出現(xiàn)這樣的情況:重構(gòu)到某個(gè)階段,發(fā)現(xiàn)行不通,然后一拍腦袋說(shuō),哦,原來(lái)這塊的架構(gòu)是這個(gè)樣的,是為了達(dá)到某某業(yè)務(wù)需求啊,這塊不能動(dòng),得想別的辦法。類似的例子在研發(fā)團(tuán)隊(duì)中時(shí)有發(fā)生,也提醒我們要慎重小心。記得有位哲人說(shuō)過(guò),了解別人很容易,了解自己很難。
檢查清單:
- 你了解當(dāng)前的架構(gòu)設(shè)計(jì)嗎?它的設(shè)計(jì)初衷和之前的選型方案知道嗎?
- 你能給架構(gòu)設(shè)定一個(gè)基準(zhǔn)狀態(tài)嗎?
不要忽略數(shù)據(jù)
數(shù)據(jù)的重要性不言而喻,業(yè)務(wù)都是以數(shù)據(jù)流為載體的,所以架構(gòu)重構(gòu)的本質(zhì)就是對(duì)于數(shù)據(jù)流的重構(gòu)。數(shù)據(jù)對(duì)重構(gòu)的重要性主要體現(xiàn)在兩個(gè)方面:在重構(gòu)設(shè)計(jì)時(shí),需要考慮業(yè)務(wù)數(shù)據(jù)的需求,重構(gòu)之后的系統(tǒng)對(duì)于數(shù)據(jù)的存儲(chǔ)、處理、分析等功能是否有影響;在重構(gòu)過(guò)程中,考慮依靠數(shù)據(jù)甚至是實(shí)際的數(shù)據(jù)來(lái)驗(yàn)證重構(gòu)的效果,提供評(píng)估的支持。
檢查清單:
- 業(yè)務(wù)數(shù)據(jù)的需求在重構(gòu)設(shè)計(jì)中有體現(xiàn)嗎?
- 重構(gòu)過(guò)程中能否通過(guò)實(shí)際數(shù)據(jù)來(lái)驗(yàn)證效果?
管理好技術(shù)債務(wù)
技術(shù)債務(wù)在平常的軟件研發(fā)過(guò)程中也是比較突出的問(wèn)題,現(xiàn)在單獨(dú)拿出來(lái)強(qiáng)調(diào)是希望提醒開(kāi)發(fā)者們:架構(gòu)重構(gòu)往往是為了償還技術(shù)債務(wù),所以請(qǐng)不要在償還技術(shù)債務(wù)的過(guò)程中制造技術(shù)債務(wù)了。技術(shù)債務(wù)就像信用卡一樣,會(huì)有很高的利息率,就如同給團(tuán)隊(duì)留下了大量的帳務(wù)開(kāi)銷。組織應(yīng)該培養(yǎng)一種保證設(shè)計(jì)質(zhì)量的文化。應(yīng)當(dāng)鼓勵(lì)重構(gòu)、同時(shí)也應(yīng)當(dāng)鼓勵(lì)持續(xù)設(shè)計(jì)以及其它有關(guān)代碼質(zhì)量的實(shí)踐。在開(kāi)發(fā)時(shí)間中應(yīng)當(dāng)專門抽出一部分以解決技術(shù)債務(wù)。如果沒(méi)有合適的照料,那么真實(shí)世界中的代碼會(huì)變得越來(lái)越復(fù)雜難懂。
檢查清單:
- 團(tuán)隊(duì)對(duì)技術(shù)債務(wù)有跟蹤和備忘錄機(jī)制嗎?還是開(kāi)發(fā)人員可以隨意的產(chǎn)生債務(wù)?
- 針對(duì)技術(shù)債務(wù)有定期的培訓(xùn)、回顧機(jī)制嗎?
遠(yuǎn)離那些虛榮的東西(例如使用“熱門”的技術(shù)棧)
架構(gòu)的重構(gòu)過(guò)程應(yīng)該是以目標(biāo)為導(dǎo)向,換句話說(shuō)“注重實(shí)效”。對(duì)于技術(shù)人來(lái)說(shuō),一個(gè)經(jīng)常被輕視的問(wèn)題在于,喜歡追逐新鮮的熱門技術(shù),這其實(shí)是個(gè)好事情,說(shuō)明技術(shù)人勇于創(chuàng)新,不斷接受新技術(shù)。但是對(duì)于架構(gòu)的重構(gòu)這樣的關(guān)鍵性任務(wù)來(lái)說(shuō),是不是新技術(shù)并不重要,重要的是能不能實(shí)現(xiàn)重構(gòu)的目標(biāo)。對(duì)于新技術(shù)來(lái)說(shuō),雖然熱度大,但是人才儲(chǔ)備還不足,大家踩過(guò)的坑還不多,積累的失敗教訓(xùn)和成功經(jīng)驗(yàn)還不夠,在這種情況下,建議大家不要頭腦一熱就上馬新技術(shù),應(yīng)該客觀冷靜地評(píng)估新技術(shù)和成熟技術(shù)對(duì)架構(gòu)重構(gòu)的影響和效果,以數(shù)據(jù)和經(jīng)驗(yàn)來(lái)說(shuō)話,而不要追趕時(shí)髦。
檢查清單:
- 重構(gòu)的技術(shù)選型是否有詳實(shí)的數(shù)據(jù)和專家評(píng)估?
- 選用的技術(shù)是否有良好的人才積累和足夠的經(jīng)驗(yàn)支持?你是不是實(shí)驗(yàn)小白鼠?
- 在技術(shù)選型時(shí),是否至少有兩個(gè)方案待評(píng)估?有沒(méi)有成熟的技術(shù)方案?
做好準(zhǔn)備面對(duì)壓力
這條軍規(guī)更像是對(duì)架構(gòu)師們的心理建議,軟件開(kāi)發(fā)過(guò)程中,壓力無(wú)處不在。對(duì)于架構(gòu)重構(gòu)來(lái)說(shuō),壓力來(lái)源于多個(gè)方面:管理層、團(tuán)隊(duì)成員、同級(jí)部門等等。說(shuō)白了,架構(gòu)重構(gòu)對(duì)個(gè)人來(lái)說(shuō)往往是一件出力不討好的事情。和做一個(gè)新產(chǎn)品能夠取得很高的贊賞相比,重構(gòu)的成績(jī)往往并不受領(lǐng)導(dǎo)重視,而且出了問(wèn)題還要承擔(dān)很大的責(zé)任。從軟件開(kāi)發(fā)角度看,做新產(chǎn)品是從0到1,而架構(gòu)重構(gòu)是從-1到1,復(fù)雜性和難度通常更大。因此,重構(gòu)的負(fù)責(zé)人要提前做好心理準(zhǔn)備,舒緩壓力的一個(gè)技巧是,設(shè)置好里程碑,將重構(gòu)的成果量化,并且和業(yè)務(wù)的變化關(guān)聯(lián)起來(lái),定期向利益相關(guān)各方同步狀態(tài),得到大家的理解和支持。
檢查清單:
- 架構(gòu)的重構(gòu)是否得到了管理層(特別是最高管理層)的支持?他們是否對(duì)重構(gòu)的時(shí)間、任務(wù)量有直接的認(rèn)識(shí)?
- 你的重構(gòu)計(jì)劃中是否包含了一些可以量化的成果?是否定期向管理層展示這些成果?
了解業(yè)務(wù)
雖然看起來(lái)像是一句廢話,但是我想Raffi Krikorian特意把這條提出來(lái)一定是有理由的。架構(gòu)重構(gòu)的最終目的是改進(jìn)業(yè)務(wù),所以對(duì)于業(yè)務(wù)的了解將有助于架構(gòu)師和技術(shù)人確定重構(gòu)目標(biāo)的優(yōu)先級(jí)和關(guān)鍵路徑。比如,我們需要知道哪些關(guān)鍵業(yè)務(wù)的架構(gòu)是不能碰的,哪些業(yè)務(wù)之間是互相關(guān)聯(lián)的,哪些業(yè)務(wù)的架構(gòu)是需要優(yōu)先重構(gòu)的.....等等。除了了解業(yè)務(wù)本身,我們還需要了解“人”,表面上管理層是重構(gòu)目標(biāo)的裁決者,但實(shí)際上業(yè)務(wù)部門的人才是。技術(shù)人需要了解他們的業(yè)務(wù)需求,并將其轉(zhuǎn)化為重構(gòu)目標(biāo)。通過(guò)這種方式,架構(gòu)重構(gòu)的意義才能得到具體的體現(xiàn)。
檢查清單:
- 是否與業(yè)務(wù)部門就架構(gòu)重構(gòu)所能實(shí)現(xiàn)的業(yè)務(wù)目標(biāo)進(jìn)行過(guò)充分的討論和確認(rèn)?
- 是否對(duì)關(guān)鍵業(yè)務(wù)和優(yōu)先重構(gòu)的業(yè)務(wù)進(jìn)行了確認(rèn)?
做好面對(duì)非技術(shù)因素的準(zhǔn)備
恩......這又是一個(gè)不那么讓人舒服的建議。不管你是否愿意相信,技術(shù)在架構(gòu)重構(gòu)(以及其他很關(guān)鍵的公司決策中)的影響因素中并不是最高的,我們還會(huì)涉及到商業(yè)利益、管理層偏好、大客戶影響、辦公室zhengzhi、站隊(duì)問(wèn)題等等,對(duì)于架構(gòu)師和技術(shù)人來(lái)說(shuō),這些因素往往不是他們所能掌控的。我們能做的就是,與利益相關(guān)者設(shè)定重構(gòu)目標(biāo),然后,根據(jù)不同的影響因素,調(diào)整目標(biāo)。請(qǐng)記住,不要死扛這個(gè)目標(biāo),當(dāng)有人提出不同的意見(jiàn)時(shí),要坦誠(chéng)地和他們交流,并告知他們?nèi)绾尾杉{意見(jiàn),那么重構(gòu)目標(biāo)會(huì)有變化,然后讓其他利益相關(guān)者也知道這些變化。非技術(shù)因素的影響是客觀存在的,而且從商業(yè)層面來(lái)說(shuō)也是合理的,所以對(duì)于技術(shù)人來(lái)說(shuō)要學(xué)會(huì)適應(yīng)。
檢查清單:
- 當(dāng)非技術(shù)因素影響架構(gòu)的重構(gòu)時(shí),你是否對(duì)目標(biāo)做了調(diào)整并告知了利益相關(guān)各方?
- 你是否準(zhǔn)備以開(kāi)放而不是抵制的心態(tài)來(lái)對(duì)待非技術(shù)因素的影響?
對(duì)于代碼質(zhì)量有所掌握
這和上篇中所提到的“管理好技術(shù)債務(wù)”有異曲同工之處。架構(gòu)的重構(gòu)對(duì)代碼質(zhì)量要求很高,一方面是重構(gòu)過(guò)程對(duì)bug的容忍性比新產(chǎn)品的研發(fā)更低,另一方面也決定了下一次重構(gòu)的難易程度。關(guān)于代碼質(zhì)量的書籍和文章已經(jīng)有很多,在這里只想提醒大家一點(diǎn):代碼審查是一個(gè)非常好的辦法。代碼審查是軟件開(kāi)發(fā)過(guò)程中的必要步驟,既可以幫助被審查者提到代碼質(zhì)量,又可以讓審查者加深對(duì)產(chǎn)品的理解。不論團(tuán)隊(duì)多忙,一定要保證代碼提交之前,是經(jīng)過(guò)其他成員審核過(guò)的,短期來(lái)看會(huì)占用團(tuán)隊(duì)的時(shí)間,長(zhǎng)期來(lái)看是事半功倍的好事。
檢查清單:
- 團(tuán)隊(duì)成員是否對(duì)代碼質(zhì)量有足夠的重視?是否有獎(jiǎng)懲措施?
- 團(tuán)隊(duì)內(nèi)部是否有代碼質(zhì)量的標(biāo)準(zhǔn)文檔和審查流程?
讓團(tuán)隊(duì)做好準(zhǔn)備
這是Raffi Krikorian列舉的最后一條軍規(guī),是對(duì)之前所有建議的總結(jié),我在這里不做解讀了,請(qǐng)大家自我感覺(jué)吧。
結(jié)尾
關(guān)于架構(gòu)的重構(gòu),Raffi Krikorian給了很好的建議,不過(guò)到底有沒(méi)有效果,還是要實(shí)踐中檢驗(yàn)。盡信書不如無(wú)書,來(lái)源于實(shí)踐中的經(jīng)驗(yàn)是最有價(jià)值的,為技術(shù)人所用才有意義。