也許您對軟體設計存在一些疑惑,或者缺乏明確思路,那麼本文將非常適合您。
我們可以看一下週邊的事物,那些好的東西,他們並不會天然存在,都是被設計出來的,因此設計就是創造和改善事物的重要過程。設計的重要之處在於,最初的設計往往決定最終的結果,甚至決定著事物的長期的發展。例如兩個品牌的手機之間,他們可以使用同一個代工廠,但他們差異在設計時就已經決定了。
架構設計也是如此,我見過很多的軟體系統,他們經過了很多年的演進,在沒有完全重構的情況下,始終無法改變最初設計模樣,最初的設計決定了長期的發展。而對於業務深度耦合的系統,重構成本非常高,風險也非常大,變化也更加不確定,所以要更加重視設計。
我們要尋求更好的技術方案,推動架構的良性演進,每一步都是經過深度思考的,而架構設計方法就是幫助我們思考的框架。
通過做架構設計,我們應該提升軟體的質量和效率,降低風險和成本。
是為了解決軟體系統複雜度帶來的問題(架構的目標是用於管理複雜性、易變性和不確定性,以確保在長期的系統演化過程中,一部分架構的變化不會對其它部分產生不必要的負面影響。這樣做可以確保業務和研發效率的敏捷,讓應用的易變部分能夠頻繁地變化,對應用的其它部分的影響儘可能地小。)
要解決複雜度問題,首先需要識別複雜度的來源,主要集中在以下三個方面:
業務複雜度:流程多,參與者多、狀態和變數多等;由業務本身決定,但業務複雜不代表軟體系統複雜,例如工作流引擎並不複雜,但他可以做非常複雜的業務,在面對複雜業務時,我們常使用抽象思維,不要讓軟體邏輯與業務邏輯繫結在一起。
技術複雜度:高效能、高可用、高可延伸、安全,成本、規模等;這部分複雜度常常由技術本身決定,也應該由技術本身解決,通常是採用更合理的框架和工具;避免這些技術特性穿透到應用層。也可以有所取捨,在不同業務情況下,採用不同的實現程度。
設計複雜度:職責不是最小的完備的、概念不清晰的、層次不清的、業務邏輯與技術實現繫結的,元件過多以及關聯依賴複雜的;這部分是由設計不合理導致的,也是對業務系統影響最大的一部分,要通過良好的設計來解決。
找到系統中的元素並搞清楚他們之間關係(如果我們不知道系統是怎麼執行的,那麼他一定是很複雜的。對於龐大的軟體系統,如何才可以被掌控?這就需要將大系統分解為很元素,每個元素需要足夠簡單,並且元素與元素之間的關係清晰)
軟體架構是一種結構,結構中包含了一些元素和元素之間的關係描述;
元素的種類:系統、子系統、模組,元件、服務、類、介面...
關係的種類:層次關係、資料關係、呼叫關係、影響力關係...
"架構表示對一個系統的成型起關鍵作用的設計決策,架構定系統基本就成型了,這裡的關鍵性可以由變化的成本來決定。"-- Grady Booch. )
"Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change." -- Grady Booch.
合適原則:「合適優於業界領先」。 真正優秀的架構都是在企業當前人力、條件、業務等各種約束下設計出來的,能夠合理地將資源整合在一起並行揮出最大功效,並且能夠快速落地。
簡單原則:「簡單優於複雜」。 優先使用直接的不復雜的方案解決問題;
演化原則:「演化優於一步到位」。軟體需要根據業務的發展不斷地變化,架構要不斷地在實際應用過程中迭代,在某個階段必定有所取捨,但架構的演化必須是低成本的,當業務發生變化時能夠最高效的迭代;在這個過程中修復缺陷的設計,積累優秀的設計;
業務分析:梳理對業務和技術的理解和判斷、形成業務領域知識、明確的業務目標和本質的業務訴求;
系統建設:降低系統複雜性、規劃系統遠期架構、推動架構的合理演化;
技術方案:選擇合適的技術、提供對業務的解決方案,把控全域性,包括質量、效率、成本、風險;
關鍵問題:攻克難點,解決關鍵問題,指導研發落地;
知識沉澱:以體系化的表達方式,面向不同人員的檢視語言,持續完善知識系統;
過程:全域性分析業務 → 設計方案 → 概要設計 → 詳細設計 → 補充設計
視角:業務級 → 系統級 → 應用級 → 模組級 → 技術級 → 程式碼級 → 實施級;
架構師的共同作業鏈路較長,每一個過程都應該留下資料,越下游的角色往往需要更全面的資料;架構設計檔案應該包含架構師參與的所有環節,以及這些環節產生的圖文說明;不僅僅是空洞的結果,應該包含架構師的思路和想法;
這階段需要對業務需求進行全面分析,需要將名詞羅列出來,區分名詞是功能、流程、名詞、參與者的哪一種。再通過分析業務的本質並找到其中的關鍵名詞,關鍵的名詞被稱之為領域,可以圍繞關鍵的領域構建業務模型;
在這個過程中,需要統一語言、識別核心領域、按照相關性將功能歸屬到對應的領域,對領域之間的關係做出必要的描述,輸出物是名詞與解釋、領域以及擁有的能力,業務架構。
名詞的概念必須是清晰的,領域的職責必須是明確的,領域擁有的能力必須是相關的;
其中業務架構可按照場景層、功能層、領域層、依賴層劃分,例如下圖;
在完成全域性分析之後,我們應該設計技術方案,儘可能提供多個備選方案的圖文說明。需要對備選方案做充分的優劣分析,最終取捨一項最合適的方案,沒有被選擇的方案(或者取捨的部分)也要被說明;
我們需要找到各項約束條件(時間、人力、硬體等),評估在約束條件允許的情況下,哪個備選方案更合適,我們可能考慮如下方面:
方案對業務影響:主要判斷需求覆蓋程度、實現業務的短期目標、考慮業務的長期目標;
方案的技術需求:安全是否滿足、效能是否滿足、規模是否滿足、可維護性;
方案的可延伸性、方案的複雜程度、方案是否能夠演進、方案演進成本如何(高成本的 慎重考慮)、方案的影響力傳播如何(對上下游影響較大的 慎重考慮);
用以說明當前系統的元素(系統、子系統、模組,元件)以及他們之間的關係(層次關係、依賴關係)
重點是將可複用的元件抽象後下沉,越往下層越是穩定和通用,由上層承接不穩定的業務;
應用架構圖體現了層次關係,以及不完全體現了依賴關係,依賴只能是上層依賴下層,範例如下圖
用以說明支援應用所需要的硬體能力、以及外部中介軟體、網路、機房等情況;可參考下面兩張圖;
描述資料資產結構、儲存、流轉、災備的情況;最常用的是ER圖;
描述一些關鍵技術的說明,比如效能、安全、互動等;
描述技術選型和程式碼框架的說明,比如DDD推薦的菱形對稱架構,文字和圖片描述都可以;
詳細設計是對質量的把關、是對研發落地的指導;
這部分涉及的內容較多,比如服務、事件、介面、實體和值物件、時序圖、資料庫設計等等;
領域服務、領域事件
時序圖
實體關係圖
學習和使用領域驅動設計,使用正確的方法梳理和理解業務,並落實到架構過程;
儘早的介入,從業務領域建模和在產品方案階段介入、推動領域知識的傳遞、為後續做好鋪墊;
積累業務能力和洞察力,需要識別關鍵部分與輔助部分、預料可延伸部分與不變部分,識別水平能力與垂直擴充套件;
對於架構設計產物,不要只畫圖,多輔以文字表述圖中內容;
業務知識:業務架構(是對當前業務、領域、能力、流程、參與者、場景的介紹),現狀架構(是對當前架構的描述,可以包含應用架構、技術架構、部署架構、資料架構等),願景架構( 是架構應該演進到的完美情況),存在問題(現在面對的痛點、無用部分、缺陷部分)
高效能:多執行緒、佇列、快取、分片、非同步化,前置化、靜態化、預處理;
高可用:限流、降級、冗餘、災備、回滾、灰度;
擴充套件性:多型、防腐,依賴反轉(業務身份、擴充套件點、SPI),抽象化(比如流程引擎、規則引擎等)、事件驅動、設計模式;
本文部分圖片來源於網際網路
作者:京東科技 董健
來源:京東雲開發者社群