天天看點

架構之重構的 12 條軍規

【注】架構之重構的 12 條軍規(上)釋出以後,一些讀者着急要下篇,是以在這裡我把上下篇合并成一篇,讓大家可以閱讀完整版,不用分開看了。

對于開發者來說,架構設計是軟體研發過程中最重要的一環,所謂沒有圖紙,就建不了房子。在遍地 App 的網際網路時代,架構設計有了一些比較成熟的模式,開發者和架構師也可以經常借鑒。

但是,随着應用的不斷發展,最初的架構往往面臨着各種問題,比如無法滿足客戶的需求、無法實作應用的擴充、無法實作新的特性等等。在這種情況下,我們如何避免一些坑,盡量比較成功地實作架構的重構,是很多開發者和架構師亟需解決的問題。

在這裡,跟大家分享一下 Uber 的工程主管 Raffi Krikorian 的 12 條規則,并附上一些解讀,希望對大家有所啟發。

1. 确定重構的目的和必要性

看起來這個規矩有些多餘,但是請不要忽略。每一次架構的重構都是“傷筋動骨”,就像做手術一樣,即使再成功,也會傷元氣,是以決策者們首先要分析架構重構的理由和其他備選方案,明确重構的目的是為了滿足業務需求,并且是不得不做的最佳方案,然後再考慮其他問題。 有時候,經過分析就會發現,也許還有其他解決方案,比如增加計算資源,或者重構的目的不是為了業務需求,那就沒有必要做了。

檢查清單:

  • 架構重構的原因是什麼,是為了滿足業務的需要還是隻是覺得架構不好看?
  • 除了架構重構之外,還有其他備選方案嗎?是否都分析過這些方案的利弊?

2. 定義“重構完成”的界限

如果确定要重構,那麼要把目标明确下來,也就是重構的邊界條件,怎麼才算是“完成”了重構,目标要有資料量化,或者有能夠測試的辦法。這也是一個需求分析的過程,如果需求不明确,那麼規格說明書沒法寫清楚,負責重構的團隊也沒有明确的目标,不能以重構的時間或者主觀的判斷為結束的依據。前幾天和一朋友聊天,他最近在負責系統的性能優化,也要做一些重構的事情,開始的時候團隊的目标不明确,大家不知道優化到什麼程度,是以不敢下手。如果目标是提高 10%,那麼可以從細節處着手;如果是提高 50%,那可能要搞大動作才能實作了。後來目标明确之後,團隊才找到合适的辦法。

檢查清單:

  • 重構的目标可以量化,或者說可以測試嗎?
  • 重構完成的标準是什麼?得到業務部門或者上司的認可了嗎?

3. 漸進式重構

現在軟體研發最流行的就是快速疊代、持續傳遞、盡早回報。這同樣可以用在架構的重構上,重構過程的難度不亞于建構一個新産品,是以在設計重構的時候,要引入持續傳遞的流程,每一個重構步驟或者子產品都要快速部署并得到回報,以便評估重構的效果,及時作出政策調整。有的讀者會說,我們的架構重構是釜底抽薪型的,沒法漸進,隻能一蹴而就。如果是這種情況,可以考慮在另外一套拷貝的系統中做重構,經過謹慎測試之後,将資料和業務遷移過去。

檢查清單:

  • 能否把重構過程分成小的疊代,每一次改進都能盡快得到回報?
  • 重構過程中的效果能夠定期展示給業務部門或者上司嗎?

3. 确定目前的架構狀态

在啟動重構之前,團隊要對目前的架構狀态有清晰的了解,也就是設定好基準,以便評估重構的效果。據我的經驗,負責重構的架構師或者開發者,往往還沒有搞清楚現有的架構設計,就開始重構了,結果經常出現這樣的情況:重構到某個階段,發現行不通,然後一拍腦袋說,哦,原來這塊的架構是這個樣的,是為了達到某某業務需求啊,這塊不能動,得想别的辦法。類似的例子在研發團隊中時有發生,也提醒我們要慎重小心。記得有位哲人說過,了解别人很容易,了解自己很難。

檢查清單:

  • 你了解目前的架構設計嗎?它的設計初衷和之前的選型方案知道嗎?
  • 你能給架構設定一個基準狀态嗎?

5. 不要忽略資料

資料的重要性不言而喻,業務都是以資料流為載體的,是以架構重構的本質就是對于資料流的重構。資料對重構的重要性主要展現在兩個方面:在重構設計時,需要考慮業務資料的需求,重構之後的系統對于資料的存儲、處理、分析等功能是否有影響;在重構過程中,考慮依靠資料甚至是實際的資料來驗證重構的效果,提供評估的支援。

檢查清單:

  • 業務資料的需求在重構設計中有展現嗎?
  • 重構過程中能否通過實際資料來驗證效果?

6. 管理好技術債務

技術債務在平常的軟體研發過程中也是比較突出的問題,現在單獨拿出來強調是希望提醒開發者們:架構重構往往是為了償還技術債務,是以請不要在償還技術債務的過程中制造技術債務了。技術債務就像信用卡一樣,會有很高的利息率,就如同給團隊留下了大量的帳務開銷。組織應該培養一種保證設計品質的文化。應當鼓勵重構、同時也應當鼓勵持續設計以及其它有關代碼品質的實踐。在開發時間中應當專門抽出一部分以解決技術債務。如果沒有合适的照料,那麼真實世界中的代碼會變得越來越複雜難懂。

檢查清單:

  • 團隊對技術債務有跟蹤和備忘錄機制嗎?還是開發人員可以随意的産生債務?
  • 針對技術債務有定期的教育訓練、回顧機制嗎?

7. 遠離那些虛榮的東西(例如使用“熱門”的技術棧)

架構的重構過程應該是以目标為導向,換句話說“注重實效”。對于技術人來說,一個經常被輕視的問題在于,喜歡追逐新鮮的熱門技術,這其實是個好事情,說明技術人勇于創新,不斷接受新技術。但是對于架構的重構這樣的關鍵性任務來說,是不是新技術并不重要,重要的是能不能實作重構的目标。對于新技術來說,雖然熱度大,但是人才儲備還不足,大家踩過的坑還不多,積累的失敗教訓和成功經驗還不夠,在這種情況下,建議大家不要頭腦一熱就上馬新技術,應該客觀冷靜地評估新技術和成熟技術對架構重構的影響和效果,以資料和經驗來說話,而不要追趕時髦。

檢查清單:

  • 重構的技術選型是否有詳實的資料和專家評估?
  • 選用的技術是否有良好的人才積累和足夠的經驗支援?你是不是實驗小白鼠?
  • 在技術選型時,是否至少有兩個方案待評估?有沒有成熟的技術方案?

8. 做好準備面對壓力

這條軍規更像是對架構師們的心理建議,軟體開發過程中,壓力無處不在。對于架構重構來說,壓力來源于多個方面:管理層、團隊成員、同級部門等等。說白了,架構重構對個人來說往往是一件出力不讨好的事情。和做一個新産品能夠取得很高的贊賞相比,重構的成績往往并不受上司重視,而且出了問題還要承擔很大的責任。從軟體開發角度看,做新産品是從 0 到 1,而架構重構是從 -1 到 1,複雜性和難度通常更大。是以,重構的負責人要提前做好心理準備,舒緩壓力的一個技巧是,設定好裡程碑,将重構的成果量化,并且和業務的變化關聯起來,定期向利益相關各方同步狀态,得到大家的了解和支援。

檢查清單:

  • 架構的重構是否得到了管理層(特别是最高管理層)的支援?他們是否對重構的時間、任務量有直接的認識?
  • 你的重構計劃中是否包含了一些可以量化的成果?是否定期向管理層展示這些成果?

9. 了解業務

雖然看起來像是一句廢話,但是我想 Raffi Krikorian 特意把這條提出來一定是有理由的。架構重構的最終目的是改進業務,是以對于業務的了解将有助于架構師和技術人确定重構目标的優先級和關鍵路徑。比如,我們需要知道哪些關鍵業務的架構是不能碰的,哪些業務之間是互相關聯的,哪些業務的架構是需要優先重構的…等等。除了了解業務本身,我們還需要了解“人”,表面上管理層是重構目标的裁決者,但實際上業務部門的人才是。技術人需要了解他們的業務需求,并将其轉化為重構目标。通過這種方式,架構重構的意義才能得到具體的展現。

檢查清單:

  • 是否與業務部門就架構重構所能實作的業務目标進行過充分的讨論和确認?
  • 是否對關鍵業務和優先重構的業務進行了确認?

10. 做好面對非技術因素的準備

恩…這又是一個不那麼讓人舒服的建議。不管你是否願意相信,技術在架構重構(以及其他很關鍵的公司決策中)的影響因素中并不是最高的,我們還會涉及到商業利益、管理層偏好、大客戶影響、辦公室 zhengzhi、站隊問題等等,對于架構師和技術人來說,這些因素往往不是他們所能掌控的。我們能做的就是,與利益相關者設定重構目标,然後,根據不同的影響因素,調整目标。請記住,不要死扛這個目标,當有人提出不同的意見時,要坦誠地和他們交流,并告知他們如何采納意見,那麼重構目标會有變化,然後讓其他利益相關者也知道這些變化。非技術因素的影響是客觀存在的,而且從商業層面來說也是合理的,是以對于技術人來說要學會适應。

檢查清單:

  • 當非技術因素影響架構的重構時,你是否對目标做了調整并告知了利益相關各方?
  • 你是否準備以開放而不是抵制的心态來對待非技術因素的影響?

11. 對于代碼品質有所掌握

這和上篇中所提到的“管理好技術債務”有異曲同工之處。架構的重構對代碼品質要求很高,一方面是重構過程對 bug 的容忍性比新産品的研發更低,另一方面也決定了下一次重構的難易程度。關于代碼品質的書籍和文章已經有很多,在這裡隻想提醒大家一點:代碼審查是一個非常好的辦法。代碼審查是軟體開發過程中的必要步驟,既可以幫助被審查者提到代碼品質,又可以讓審查者加深對産品的了解。不論團隊多忙,一定要保證代碼送出之前,是經過其他成員稽核過的,短期來看會占用團隊的時間,長期來看是事半功倍的好事。

  • 團隊成員是否對代碼品質有足夠的重視?是否有獎懲措施?
  • 團隊内部是否有代碼品質的标準文檔和審查流程?

12. 讓團隊做好準備

結尾

繼續閱讀