可視化與領域驅動設計

從DDD的角度,領域邏輯的分析可以運用戰略方法Bounded Context??墒?,一個問題是:如何獲得Bounded Context ?

我查看了許多關于Bounded Context的書籍與文章,雖然都著重強調了它的重要性,也給出了一些實例,卻對如何從需求——>Boundex Context這一點上語焉不詳。

一個初步設想

我的初步設想是通過繪制場景圖(但并不成熟)。我認為有三種繪制場景圖的方式:商業畫布,體驗地圖和流程圖。我認為,商業畫布可以作為需求分析(尤其針對初創產品)的起點。商業畫布如下圖所示:

商業畫布

采用這種規范化的方式來推導商業模型,可以激發我們的靈感,理清我們的思路,以便我們思考為何要做這個產品,產品應該具備哪些功能。結合優點和缺點、成本等因素,我們可以藉此判斷和決策功能的優先級,從而得到MVP。這個過程需要大量運用即時貼,讓整個商業模型呈現。經過取舍后,就可以針對產品繪制場景圖。此時,場景圖可以采用Experience Map或流程圖來體現。Experience Map的例子如下圖所示:

體驗地圖

由于商業畫布本身提供了“客戶”項,我們應該創建Persona,找準人物角色的特征來“搜尋”需求。繪制了場景圖后,就能夠確定用例了,此時,可輔以ATDD幫助確定Story。在確定了用例后,可以識別Bounded Context,并通過Context Map確定上下文之間的關系。

就我個人感覺,體驗地圖還是從Persona的角度設想系統如何使用,考慮它的用戶體驗。它其實符合“場景”的概念。這里可能還是要考慮:在一個完整的場景中,需要哪些參與者?但是,即使從粗粒度的角度出發,場景都可能存在多個,可能需要繪制多個場景圖來逐步提煉Bounded Context。

關于如何運用Persona,熊子川在他的博客《XD關鍵字5:Persona》中已有詳細介紹,同樣在他的博客《Agile UX內容策略工作坊》中提出的“消費者建?!睂嵺`,指出:

為了更好的理解我們選擇的目標消費者,我們需要對消費者進行完整的建模,即Persona。越接近于真實的Persona幫助我們更好的理解其用戶目標……Persona的重要產出物是一系列用戶目標,對于同一個Persona,用戶目標可能有不同,有些目標是基礎核心目標,有些則是衍生性的,例如一個訪問網站潛在投資者的核心目標可能是了解成為投資者的過程,而衍生性目標可能是獲得一些關于公司歷史信息增加信任度。

Persona:摘自熊子川博客

獲得Context并劃分領域

假設我們要開發一個電子商務網站,我們就可以通過商業畫布來驅動出這個產品應該具有哪些功能,它的客戶有哪些等,在繪制了場景圖后,可以初步得到這樣的Bounded Context:

Bounded Context

然后,我利用Context Map得到了各個上下文之間的關系:

Context Map

這樣,一個包圖的獲得就水到渠成了:


Package Diagram

六邊形架構

在識別了Bounded Context以及Context之間的關系后,我們可以運用Hexagon架構(Cockburn提出的六邊形架構)來展現系統的整體架構。Hexagon架構并不深入關注內部邊界中領域部分,僅僅是簡單的劃分為Application與Domain兩層。但它有助于我們獲得基礎設施層以及相關集成點的包結構。我們要合理地運用六邊形架構。它更貼近應用邏輯架構,并可以驅動我們去發現諸多集成點,尋找集成模式。內外邊界的分離也有助于我們將業務邏輯與應用邏輯分離開。這實際上符合“關注點分離”的架構原則。下圖為Cockburn提出的六邊形架構:

六邊形架構

所謂“可視化架構”,是一種利用多種交流方式實現架構知識共享的方法,因而需要團隊成員均參與進來,并以Workshop的形式,更多通過即時貼、白板等工具實現可視化,而非通過繪圖。至少,繪圖不應該成為主要的驅動力,否則,開發人員很難接受。例如,下圖就是我運用Hexagon架構,并結合可視化手段分析該電子商務系統得到的應用邏輯架構,它很好地一個展現了Hexagon架構的可視化手法。

運用六邊形架構

在這個圖中,直觀地展現了如何與外部的支付系統以及物流系統的集成。例如,圖中展現的Port實際上為防腐層(ACL)。為何要建立這樣的一個防腐層呢,原因在于:支付與物流常常存在多個供應商,因而需要解除對供應商的綁定,并避免供應商系統的變化造成對電子商務系統的腐蝕。這是切合實際的決策。

一個實例:倉庫管理流程控制系統

這個電子商務系統需要與倉庫管理系統集成。恰好在《面向模式的軟件架構》卷四的第35頁,給出了一個倉庫管理流程控制系統的案例。書中描述的非功能性需求,即所謂質量屬性包括:

  • 分布性。倉庫管理流程控制系統天生就是分布式的。
  • 性能。倉庫管理流程控制系統不是一個“絕對的”實時系統,但性能仍與業務息息相關。對系統有整體的吞吐量要求,因此系統必須確保所有的運輸指令能夠被及時而有效地運行。
  • 可伸縮性。不同倉庫其大小可能會有很大的不同,因此倉庫管理流程控制系統必須能既支持只有幾千個箱子的小倉庫,又要支持超過一百萬個箱子的大倉庫。
  • 可用性。許多倉庫操作采用三班倒的24/7模式工作,因此可用性是倉庫管理流程控制系統對業務案例支持的關鍵因素。

假設要設計這樣的系統以支持這些質量屬性。對于分布式而言,書中提出的解決方案是傳統的分布式系統解決方案,即引入Broker模式,在本地建立對遠程對象的代理。而對于支持并發的領域對象訪問而言,則采用了Active Object模式,并引入Leader/Followers并發模型來獲得可擴展。

我沒有打算引入這么復雜的模式,而是通過引入消息隊列,并為消息隊列引入路由的方式,來實現系統的分布式。這其中當然會用到經典的Publisher-Subscriber模式。我對領域邏輯進行了識別,將整個倉庫管理流程控制系統的領域邏輯分為三個Bounded Context。

  • 庫存管理
  • 物流控制
  • 拓撲管理

整個架構如下圖所示:

倉庫管理流程控制系統的整體架構

對于庫存管理而言,我認為它主要支持商品存放信息的數據管理,即獲得商品數量、存放位置以及更新這些信息。對于該上下文而言,操作本身比較簡單,且耗時較短。若出現大規模并發,其瓶頸也不在于獲取或更新倉庫信息(當然需要通過測試數據驗證),而在于客戶下訂單后向倉庫管理流程控制系統發起的發貨請求。

我將發貨請求放到了物流控制上下文中,除此之外,它還包括收貨以及訂單管理等。同時,對于物流控制與拓撲管理功能,基本上與具體的倉庫形成了一一對應關系。此外,對于發貨請求(或收貨請求),并不要求很強的實時性,這使得對這些請求的異步處理成為可能。

物流控制由于牽涉到收貨和運貨,需要控制倉庫的相關設備,并按照倉庫的拓撲結構設定設備的路由。這說明物流控制與拓撲控制存在上下游關系,拓撲控制是上游。這兩個上下文可以是Customer-Provider的關系。但它們之間不應該存在物理邊界。因此,我將這兩個上下文放到了同一個六邊形中,而將庫存管理放到了另一個單獨的六邊形中,以便于它們各自獨立的可伸縮。

在庫存管理與物流控制六邊形之間,我引入消息隊列來應對從庫存管理子系統中轉發而來的發貨請求(發貨請求實則又來自于E-Commerce的訂單請求)。原則上,我針對一個物理的倉庫建立一個單獨的消息隊列,因此庫存管理在發送發貨請求時,會根據商品的存放位置以及用戶請求的IP地址,獲得最優的倉庫信息,然后通過Router將消息轉發到正確的消息隊列中。

一旦收到消息,物流控制系統作為消息隊列的訂閱者(或偵聽器)就可以及時處理信息,進行后續的處理。

針對庫存管理而言,我認為它是一個獨立的物理邊界,因此在可視化手段中,我展現為一個單獨的庫存管理六邊形,如下圖所示:

庫存管理的BC

在這個BC中,利用六邊形架構,我分別建立了如下端口:

  • 建立了針對REST服務的端口,對應的適配器為Controller,其目的是支持E-Commerce系統。事實上,我們對E-Commerce系統進行過分析,獲得的六邊形架構正好與此對接。
  • 建立了針對DB的端口,對應的適配器為DB Gateway,它負責訪問庫存管理自身的數據庫。數據庫持久化的消息包括商品的基本信息如SKU、商品名、數量等,以及商品存放的倉庫名。
  • 建立了針對Queue的端口,對應的適配器為Message Router,負責將發貨請求消息路由到正確的消息隊列。

物流控制與拓撲管理放在同一個邊界中,它是高度可伸縮的獨立系統,為展現它的可伸縮性以及它與庫存管理之間的集成,我在可視化手段中,展現出兩個獨立的六邊形,如下圖所示:

物流控制與拓撲管理的BC

我為物流控制與拓撲管理的BC建立了如下端口:

  • 針對Queue的偵聽器端口,對應的適配器為Message Handler。若有必要,例如為了更好地支持并發,也可以在此引入Active Object甚至Leader/Followers。
  • 提供了針對REST的端口,對應適配器為Controller。它主要是為了支持移動終端設備、Web應用,以便于相關人員直接發出發貨或收貨請求。
  • 提供了DB的端口。這個數據庫是對應倉庫的專有數據庫,與庫存管理數據庫無關。
  • 提供了針對設備(指倉庫的設備,如叉車,箱子,運輸車等)的端口,對應適配器為South Gateway。
  • 提供了針對配置文件的端口,對應適配器為Configurer。此功能是為了支持拓撲信息的動態配置。
  • 提供了針對外部物流系統的端口,這里為其建立了Shipping的防腐層,使其能夠更好地支持各個不同的物流供應商。

目前,我針對可視化架構與設計的手段仍在完善之中,并已經嘗試在真實項目中實踐以進行驗證,并希望能夠找到足夠簡單的方法,為架構師與開發者提供直觀而又具有體驗價值的溝通方式,并能形成行之有效的設計手段。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容