架構之:軟件架構漫談

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"簡介","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每一個程序員心中都有個架構師的夢想,架構是如此的重要,以至於每個程序員都在談架構,彷彿沒有架構的軟件是沒有靈魂的,不想做架構師的程序員不是一個好的碼農一樣。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼架構到底是什麼呢?架構是怎麼得到的呢?今天本文將會從自身的經驗來闡述一下對架構的看法。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"什麼是架構","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在軟件發展的初期是沒有架構而言的。從最早的彙編語言到過程語言,他們處理的是一個個任務,爲此編制了一個個的函數來執行對應的任務。這時候的軟件編程語言還是過程語言,所以談不上架構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着硬件技術的成熟,能夠處理的任務越來越多,爲了處理這麼多的任務,編程語言也從面向過程轉變爲面向對象,從而更好的適應任務的發展。軟件越來複雜,要處理的任務越來越多,最終導致了系統架構的產生。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"架構是在複雜軟件結構中產生的,它的任務就是讓這些複雜軟件中的任務能夠互相協作從而來完成共同的任務。當然這是從軟件的目標來說的。如果再考慮軟件的實現和擴展性,那麼好的架構需要讓系統可讀性和可擴展性更強,給未來留出一定的空間。如果從可靠性和可用性來講,好的架構還需要保證系統高可用和容錯性。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們要注意的是,架構並不是空想而來的,它的基石在於編寫的程序。所以架構需要跟程序緊密結合才能產生活力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系統的架構主要描述的是系統的主要組件和這些組件之間的關係和他們如何進行交互。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"架構的關鍵設計原則","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了最大程度的降低成本,滿足功能需求,並最大程度的提高系統結構的可擴展性和可用性,我們需要考慮下面幾個關鍵的設計原則:1. 關注點分離原則","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將系統的組件按照特定的功能進行劃分,從而是組件的功能之間沒有重複。從而保證高內聚力和低耦合度。這種方法避免了系統組件之間的相互依賴性,有助於簡化系統。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"2","normalizeStart":"2"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"單一責任原則","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"系統的每個模塊都應負一個特定的責任,這有助於用戶清楚地瞭解系統。它還有助於組件與其他組件的集成。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"3","normalizeStart":"3"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"最少知識原理","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任何組件或對象都不應該獲取其他組件的內部細節。這種方法避免了相互依賴,並提高可維護性。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"4","normalizeStart":"4"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"最大限度地減少前期的大型設計","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果應用程序的需求不清楚,則最大程度地減少前期的大型設計。從小的原型出發,在探索中確認好需求。避免後期因爲需求變動導致的巨大重構工作量。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"5","normalizeStart":"5"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"不要重複功能","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“不重複功能”指的是不要重複組件的功能,一個邏輯的實現,只應該存在於一段代碼中。如果有多處代碼的拷貝,那麼在邏輯發生變化的時候,功能的重複會使其難以實施更改,降低清晰度並引入潛在的不一致之處。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"6","normalizeStart":"6"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":6,"align":null,"origin":null},"content":[{"type":"text","text":"重用功能時要優先考慮組合而不是繼承","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"繼承會在子類和父類之間建立依賴關係,因此會阻止子類的自由使用。相反,組合提供了很大的自由度並減少了繼承層次結構。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"7","normalizeStart":"7"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":7,"align":null,"origin":null},"content":[{"type":"text","text":"定義不同層之間的通信協議","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要對部署方案和生產環境有完整的瞭解,從而制定出或者使用合適的通信協議。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"8","normalizeStart":"8"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":8,"align":null,"origin":null},"content":[{"type":"text","text":"定義組件之間交互的數據格式","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"各種組件將通過數據格式相互交互。最好統一數據格式,從而使應用程序易於實現,擴展和維護。通過使用相同的數據格式,以便各個組件在相互通信時無需對數據進行編碼/解碼。它減少了處理開銷。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"9","normalizeStart":"9"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":9,"align":null,"origin":null},"content":[{"type":"text","text":"系統服務組件應該是抽象的","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與安全性,通信或系統服務(例如日誌記錄,概要文件和配置)相關的代碼應在單獨的組件中抽象出來。請勿將此代碼與業務邏輯混合使用,這樣擴展設計和維護將會變得容易。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"10","normalizeStart":"10"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":10,"align":null,"origin":null},"content":[{"type":"text","text":"設計異常和異常處理機制","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"預先定義異常,有助於組件以優雅的方式管理錯誤或意外情況。最好在整個系統中使用相同的異常處理機制。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":"11","normalizeStart":"11"},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":11,"align":null,"origin":null},"content":[{"type":"text","text":"命名約定","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"命名約定應事先定義。它們提供了一個一致的模型,可以幫助用戶輕鬆理解系統。團隊成員更容易驗證其他人編寫的代碼,因此會增加可維護性。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"架構的描述","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然架構這麼重要,我們可以使用什麼樣的手段才能夠描述架構中的組件、組件之間的聯繫和他們的交互呢?業界也探討了很多方法。這裏我們也來介紹幾種方法。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"UML","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UML大家應該都很熟悉了,它的全稱是統一建模語言,它是一種圖形語言。UML1.0規範是在1997年1月由對象管理組(OMG)提出的。它用作軟件需求分析和設計文檔的標準,這些文檔是開發軟件的基礎。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UML是可視化的建模語言,裏面包含很多組件,這些組件通過不同的方式關聯,從而形成了完整的UML圖。儘管通常使用UML對軟件系統進行建模,但它並不侷限於此範圍。UML也被用於建模非軟件系統,例如製造單元中的流程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UML主要分成兩大類別:結構圖和行爲圖。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"結構圖表示系統的靜態組件。 這些靜態組件由類,接口,對象,組件和節點表示。結構圖包含下面幾個部分:","attrs":{}}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"類圖: 表示面向對象系統中的各個類和他們間的關係。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"對象圖:對象圖表示的是運行時的對象和他們的關係。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"組件圖:組件圖描述的是系統中的所有組件、接口和他們的交互關係。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"複合結構:描述組件的內部結構,包括所有類,組件的接口等。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"包:包主要是包含類和其他的包。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":6,"align":null,"origin":null},"content":[{"type":"text","text":"部署圖:部署圖是一組節點及其關係。 這些節點是部署組件的物理實體。","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"行爲圖表示的是系統中可能出現的動作,行爲圖可以包含下面幾種:","attrs":{}}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"用例圖:描述功能及其內部/外部控制器之間的關係。 這些控制器被稱爲參與者。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"活動圖:描述系統中的控制流。 它由活動和鏈接組成。 該流可以是順序的,併發的或分支的。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"狀態圖:表示系統的事件驅動狀態更改。 它描述了類,接口等的狀態變化。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"序列圖:可視化系統中執行特定功能的順序。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"組合活動圖和序列圖以提供系統和業務流程的控制流概述。","attrs":{}}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"架構視圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"視圖是從一組相關關注點的角度對整個系統的表示。它用於從不同的利益相關者(例如最終用戶,開發人員,項目經理和測試人員)的角度描述系統。這裏給大家介紹一個叫做4 + 1的視圖模式。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4 + 1視圖模型是由Philippe Kruchten發明的。該模型基於對多個視圖和併發視圖的使用來描述軟件密集型系統的體系結構。它是一個多視圖模型,解決了系統的不同功能和關注點。它使軟件設計文檔標準化,並使所有利益相關者易於理解設計。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它包含了4個基本的視圖,分別是:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"1. 邏輯視圖或概念視圖-它描述了設計的對象模型。 \n 2. 流程視圖-描述了系統的活動,包括併發和同步。 \n 3. 物理視圖-它描述了軟件到硬件的映射並反映了其分佈式關係。 \n 4. 開發視圖-它描述了環境開發中軟件的靜態組織和結構。\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後的+1視圖表示的是爲最終用戶或客戶添加一個稱爲方案視圖或用例視圖的視圖。它和其他的4個視圖是一致的,所以被稱爲+1 視圖。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"ADL","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"架構描述語言ADL是一種語言,提供用於定義軟件體系結構的語法和語義。它是一種註釋規範,提供了用於對軟件系統的概念體系結構進行建模的功能,這與系統的實現有所不同。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"架構描述語言是一種形式化的規範語言,它描述諸如進程,線程,數據和子程序之類的軟件功能,以及諸如處理器,設備,總線和內存之類的硬件組件。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"今天的架構漫談就講到這裏,有不住之處還希望大家多多指正。後續會給大家介紹幾種常見的架構模式。希望大家能夠喜歡。","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"本文已收錄於 ","attrs":{}},{"type":"link","attrs":{"href":"http://www.flydean.com/06-software-architecture/","title":null,"type":null},"content":[{"type":"text","text":"http://www.flydean.com/06-software-architecture/","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"最通俗的解讀,最深刻的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"歡迎關注我的公衆號:「程序那些事」,懂技術,更懂你!","attrs":{}}]}],"attrs":{}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章