架構師必須知道的架構設計原則


不管你是新手程序員、職場老司機,還是資深架構師,這篇文章對你來說應該都有裨益。雖然仍是假期,但也建議你多花點時間讀一讀這些真言。
寫在前面
如果一個技術已經存在 2 年,比如現在很火的前端技術 react 和 vue 等,那么我能預估這個技術大致還有 2 年的生命期,再久就不確定了;如果一個架構或設計原則已經存在 15 年,例如單一職責和依賴倒置原則,我可以預期它還有 15 年甚至更久的生命期。原則是比具體技術更抽象,更接近事物本質,也更經得起時間考驗的東西。這些原則沉淀在架構師的腦海中,最終內化成他的 mindset,以潛意識方式影響和指導他的架構和設計工作。
一晃我在軟件研發行業工作十多個年頭了,前面大部分時間做架構設計和開發,現在轉型做研發管理。隨着時間的推移,很多技戰術細節性的東西 (工具,框架,編程語言) 在我腦海中漸漸模糊,但是一些平時學習積累起來,並且在實踐中加深體會的軟件架構設計和組織原則,這些原則性的東西卻絲毫沒有被時間沖淡,反而愈加清新。現在即使我不在一線開發,但這些沉淀下來的原則仍然潛移默化地影響我的日常管理和部分架構設計指導工作。我想有必要總結一下那些業界知名,給我留下深刻印象的軟件架構設計和組織原則,和大家一起分享。
軟件設計原則
GRASP 通用職責分配軟件模式
來自 Craig Larman 的軟件設計書《UML 和模式應用》[附錄 1],Larman 在書中提出軟件設計的關鍵任務是職責分配,並提煉總結出 9 種 (5 種核心 +4 種擴展) 軟件職責分配模式,這些模式是比 GoF 設計模式更抽象的元模式。
1. 信息專家 (Information Expert)
為對象分配職責的通用原則 – 把職責分配給擁有足夠信息可以履行職責的專家
2. 創建者 (Creator)
將創建 A 的職責賦給 B,如果至少下面一種情況為真:
  • B“包含”或者聚合 A
  • B 記錄 A 的實例
  • B 密切地使用 A
  • B 擁有 A 的初始化數據
    3. 低耦合 (Low Coupling)
    賦予職責使得對象間的耦合度盡可能低,最小化對象間的依賴和變更影響,最大化重用。
    4. 高內聚 (High Cohesion)
    賦予職責使得每個對象的職責盡可能保持聚焦和單一,易於管理和理解。
    5. 控制器 (Controller)
    把職責賦予系統、設備或者子系統的表示類 (門面控制器),或者某個用例的表示類 (用例控制器),讓控制器接收事件並協調整個系統的運作。
    6. 多態 (Polymorphism)
    將職責分配給多個具有同名方法的多態子類,運行時根據需要動態切換子類,讓系統行為變得可插拔。
    7. 純虛構 (Pure Fabrication)
    針對真實問題域中不存在,但是設計建模中有用的概念,設計虛構類並賦予職責。
    8. 間接 (Indirection)
    在兩個或者多個對象間有交互的情況下,為避免直接耦合,提高重用性,創建中間類並賦予職責,對象的交互交由中間類協調。
    9. 受保護的變化 (Protected Variation)
    簡單講就是封裝變化。識別系統中可能的不穩定或者變化,在不穩定組件上創建穩定的抽象接口,將可能的變化封裝在接口之后,使得系統內部的不穩定或者變化不會對系統的其它部分產生不良影響。
    SOLID 面向對象設計原則
    S.O.L.I.D 是面向對象設計和編程 (OOD&OOP) 中幾個重要原則的首字母縮寫,受 Robert Martin 推崇。
    1. 單一職責原則 (The Single Responsibility Principle)
    修改某個類的理由應該只有一個,如果超過一個,說明類承擔不止一個職責,要視情況拆分。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/E164B18101464A4F969C9629937F52A2/2480)
2. 開放封閉原則 (The Open Closed Principle)
軟件實體應該對擴展開放,對修改封閉。一般不要直接修改類庫源碼(即使你有源代碼),通過繼承等方式擴展。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/14CA4061A37744DB864BB0AE064E13D0/2483)
3. 里氏替代原則 (The Liskov Substitution Principle)
當一個子類的實例能夠被替換成任何超類的實例時,它們之間才是真正的 is-a 關系。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/46A909D248D042758244123824E4633F/2485)
4. 依賴倒置原則 (The Dependency Inversion Principle)
高層模塊不應該依賴於底層模塊,二者都應該依賴於抽象。換句話說,依賴於抽象,不要依賴於具體實現。比方說,你不會把電器電源線焊死在室內電源接口處,而是用標准的插頭插在標准的插座 (抽象) 上。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/87E1DE11C3C942E4B5857B13ACE993AF/2481)
5. 接口分離原則 (The Interface Segregation Principle)
不要強迫用戶去依賴它們不使用的接口。換句話說,使用多個專門的接口比使用單一的大而全接口要好。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/1E41A4692C4A429C89406259647F2613/2482)
我的解讀
  1. 我職業早年主要關注軟件設計和編程,所以花蠻多時間學習和消化 GRASP 和 SOLID 設計原則。這些原則對我影響很深,尤其是單一職責,信息專家,關注分離,依賴倒置 / 封裝變化,分而治之等核心原則,現在日常研發中我時常用這些原則指導新手工程師。

  2. 高內聚 + 低耦合,就像道中的一陰一陽,是所有其它 OO 設計原則的原則 (元原則),其它設計原則都是在這兩個基礎上泛化衍生出來的。

  3. 上述原則雖然是針對 OO 設計和編程提出,但是對於大規模系統架構仍然適用。比如,微服務架構就體現了:

  4. 作為架構師或者設計師,有兩個設計能力是需要重點培養的,也是最難和最能體現架構設計水平的:

分布式系統架構設計原則和理論
AKF 架構原則
這 15 個架構原則來自《架構即未來 (The Art of Scalability)》[附錄 2] 一書,作者馬丁 L. 阿伯特和邁克爾 T. 費舍爾分別是 eBay 和 PayPal 的前 CTO,他們經歷過 eBay 和 PayPal 大規模分布式電商平台的架構演進,在一線實戰經驗的基礎上總結並提煉出 15 條架構原則:
1.N + 1 設計
永遠不要少於兩個,通常為三個。比方說無狀態的 Web/API 一般部署至少>=2 個。
2. 回滾設計
確保系統可以回滾到以前發布過的任何版本。可以通過發布系統保留歷史版本,或者代碼中引入動態開關切換機制 (Feature Switch)。
3. 禁用設計
能夠關閉任何發布的功能。新功能隱藏在動態開關機制 (Feature Switch) 后面,可以按需一鍵打開,如發現問題隨時關閉禁用。
4. 監控設計
在設計階段就必須考慮監控,而不是在實施完畢之后補充。例如在需求階段就要考慮關鍵指標監控項,這就是度量驅動開發 (Metrics Driven Development) 的理念。
5. 設計多活數據中心
不要被一個數據中心的解決方案把自己限制住。當然也要考慮成本和公司規模發展階段。
6. 使用成熟的技術
只用確實好用的技術。商業組織畢竟不是研究機構,技術要落地實用,成熟的技術一般坑都被踩平了,新技術在完全成熟前一般需要踩坑躺坑。
7. 異步設計
能異步盡量用異步,只有當絕對必要或者無法異步時,才使用同步調用。
8. 無狀態系統
盡可能無狀態,只有當業務確實需要,才使用狀態。無狀態系統易於擴展,有狀態系統不易擴展且狀態復雜時更易出錯。
9. 水平擴展而非垂直升級
永遠不要依賴更大、更快的系統。一般公司成長到一定階段普遍經歷過買更大、更快系統的階段,即使淘寶當年也買小型機扛流量,后來扛不住才體會這樣做不 scalable,所以才有后來的去 IOE 行動。
10. 設計時至少要有兩步前瞻性
在擴展性問題發生前考慮好下一步的行動計划。架構師的價值就體現在這里,架構設計對於流量的增長要有提前量。
11. 非核心則購買
如果不是你最擅長,也提供不了差異化的競爭優勢則直接購買。避免 Not Invented Here 症狀,避免凡事都要重造輪子,畢竟達成業務目標才是重點。
12. 使用商品化硬件
在大多數情況下,便宜的就是最好的。這點和第 9 點是一致的,通過商品化硬件水平擴展,而不是買更大、更快的系統。
13. 小構建、小發布和快試錯
全部研發要小構建,不斷迭代,讓系統不斷成長。這個和微服務理念一致。
14. 隔離故障
實現故障隔離設計,通過斷路保護避免故障傳播和交叉影響。通過艙壁泳道等機制隔離失敗單元 (Failure Unit),一個單元的失敗不至影響其它單元的正常工作。
15. 自動化
設計和構建自動化的過程。如果機器可以做,就不要依賴於人。自動化是 DevOps 的基礎。
我的解讀
  1. 這 15 條架構原則基本上是 eBay 在發展,經歷過流量數量級增長沖擊過程中,通過不斷踩坑踩出來的,是干貨中的干貨。消化吸收這 15 條原則,基本可保系統架構不會有原則性問題。
  2. 這 15 條原則同樣適用於現在的微服務架構。eBay 發展較早,它內部其實很早 (差不多 2010 年前) 就已形成完善的微服務生態,只是沒有提出微服務這個概念。
  3. 這 15 條原則可根據 TTM(Time To Market),可用性 / 可擴展性 / 質量,成本 / 效率分布在三個環內,如下圖所示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM