C4 模型 - 可視化架構設計

   前言

  世界上最難的兩件事是:

  1. 把我的思想放進你的腦袋

  2. 把你的錢放進我的口袋  

  第二點我們不探討,因爲這是衆所周知的,不信?過來試試:)  

  對於第一點,對我們程序員來說,其實也是我個人一直強調的,很多事情的成敗,其實就在於掌舵人的思想層面是否認知是一致的,當我們對於一個事物的認知不在同一層面,就好比我們的划槳是不統一的,這是不能發揮最大的生產力。

  你碰到過嗎?

  當我們進入一家新公司的時候,每個人都需要對公司的業務系統進行了解,當你不得不向別人解釋系統是如何工作的,業務模塊是如何串聯的,子系統是如何各司其職的,特別是對於非技術人員來說,你會從代碼開始解釋嗎?

  如果是這樣的話,這將是最低效且會讓人陷入無窮無盡的技術細節裏面,如何清晰描述系統讓不同人找到自己的關注點,將成爲難題。

  通常我們會從宏觀的架構設計上進行講解,然而當我們在探討架構設計的時候,每個人對架構的抽象層次理解都不一樣,抽象這種東西,說起來好像存在,但是要具體描述乃至落筆下來,還是非常有難度的。

  所以我們需要的是:讓程序員和業務人員在討論系統時候,能有統一的維度和統一標準,這就像是領域驅動設計裏面所提倡的統一語言,讓所有人在統一的認識中有效的溝通。

  鑑於這樣的背景,C4 model提出這樣的概念來解決這個問題。

  C4 模型

  C4的理念是,具體把系統分爲:System Context(上下文), Container(容器), Component(部件), Code(代碼)這四層,每層代表着不同的視圖架構,關注點也會不同,所以每層適用於不同的人員,我們會針對當前的人員的角色,找到共同的關注點(合適的層級)來統一認識,然後拓展話題。

  當我們使用C4模型來描述自己的軟件架構時,可以通過不停的放大,把架構從宏觀到細節具體地描述出來。就好比我們看地圖一樣,總覽(System Context)關注的是國家層面,然後到省(Container)的層面,由多個省來構成國家,再下一層,到市(Container),再到市是如何建設起來的(Code)。這四種不同的抽象層次的定義會讓我們更容易固定住我們討論的層次以及共同認識。

 

 

 

  我們來看一下每一層的具體含義。

  第一層 -  System Context

  在這一層,我們將不會關注細節,這裏提供的是系統級別的總覽關係圖,這層的關注點應該是用戶和系統的交互,而不是協議,技術點等一些具體的體現。所以它的使用人羣是非技術人員,這裏面描述的是系統級別的交互,誰使用。

 

  在這裏,我們可以理解這是一個可供終端用戶使用的完整系統(或者多個系統)的描述和專注於該層的使用人員,這裏的一個系統可由一個或者多個服務(進程)組成,能完成我們業務的服務組合。所以看到我們用戶直接面對的是可用的系統,而一些郵件和權限系統,則屬於子系統。

  在這裏的一些特定技術術語需要澄清一下:一個系統可由多個服務(微服務)組成,也可只有一個服務組成(郵件系統很可能只有一個郵件的收發服務)。

  需要特別注意的是,在跟別人探討這層的時候,儘可能不要引入技術術語,因爲這層更多的是使用人員關注的,大家的認知應該是在對系統的正常理解。

  第二層 - Container

  這一層是上一層Context的繼續(我們這裏選擇的是用業務系統這個系統作爲例子),是我們將各個System Context放大(Zoom in)的效果,我們將會看到一個技術棧以及各模塊的一個職責和依賴。

   

  這層是給具有技術背景的人員看,這裏面描述的是進程級別的應用,這是可直接部署和運行的,通過這層,我們將可以看清軟件整體形態以及職責描述。

  這裏的Container也可以理解爲容器,因爲我們的應用進程也是按容器爲單位部署的。

  第三層 - Component

   這一層是Container層的繼續放大,這裏將看到服務的具體組成,如我們的訂單服務包含哪些職責的類

  我們可以看到,這一層是給開發人員看,這裏描述的是系統組成部件、部件之間的層級關係和依賴。

  這層的Component,可以理解爲java裏面的包或者c#裏面的程序集,這裏描述的是內部的包/程序集相互引用(調用)關係以及包對外部系統的程序的依賴

  第四層 - Code

  這一層是持續將Component放大的效果(借用一下官網的類圖:))。

 

  這一層的使用對象是開發人員,這裏描述的是基於UML等圖形來描述實現的技術細節,直接反映了代碼層面。

  找到共同語言

  好了,當我們把整個系統通過通過C4 模型設計把不同層次的抽象軟件架構描述了出來,我們可以找到各自所關心的層次進行快樂的交流了。

  什麼?你想給剛來的產品經理講Component級別的架構?不,你不想,你也不能想,因爲他並不關心這個,你能講的,就是基於Context級別,講述我們公司的整個產品體系是如何運行以及關聯依賴的。

  所以,回到我們的前言:讓所有人在統一的認識中有效的溝通。這讓我們在探討之前,先找好各自關心的層次,然後再進行交流。這也是C4 模型給我們帶來的巨大價值。

  我們如何落地?

  說了那麼多概念,可以來點乾貨了,如何動手把腦袋中的架構展示出來?

  PlantUML

  什麼是PlantUML? PlantUml是一個支持快速繪製的開源項目,其定義了一套完整的語言,通過文字、代碼等工具用於實現UML關係圖的描述。

  通過PlantUML,我們可以輕鬆通過代碼形式畫出自己想要的圖形。 

  這裏採用一個流程圖作爲例子: 

@startuml
用戶 -> 認證中心: 登錄操作
認證中心 -> 緩存: 存放(key=token+ip,value=token)token

用戶 <- 認證中心 : 認證成功返回token
用戶 -> 認證中心: 下次訪問頭部攜帶token認證
認證中心 <- 緩存: key=token+ip獲取token
其他服務 <- 認證中心: 存在且校驗成功則跳轉到用戶請求的其他服務
其他服務 -> 用戶: 信息
@enduml

  

  PlantUML不僅僅能畫出C4 模型架構,還能輕鬆畫出常用的UML圖,以及通過安裝插件,實現draw.io ,xmind等插件的圖形繪畫。

  使用PlantUML刻畫C4

   在VSCode中下載PlantUML插件,然後在GitHub上搜索一些好用的PlantUML開源庫,直接代碼形式畫圖吧。

 

   補充個人上面圖形的PlantUML源碼:)

   總結

  軟件架構圖是一種非常好的表達方式,可以用它們來表達你將如何構建一個軟件系統或者現有的軟件系統是如何工作的,而C4 模型則能很好的解決這個問題,它是由一系列分層的軟件架構圖組成,這些架構圖用於描述不同層次的不同的抽象,每層的抽象都會有不同的適用人羣。

  當我們擁有了C4 模型的方法論之後,面對不同角色人員,我們將清楚的知道,應該宣講哪層以及該把關注點放在哪層,這樣我們將會在統一的意識層面上探討,做到意識上的統一。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章