l

2016年11月7日 星期一

領域驅動設計學習筆記(4):Bounded Context

Nov. 04 14:40~16:57

image

▲節錄自Google Map

 

現況

鄉民們開發軟體,尤其是大型軟體,通常包含著多個模型(model),例如電子商務系統系統可能包含購物模型、庫存管理模型、產品目錄管理模型、權限管理模型、客戶關係管理模型、帳務管理模型、物流管理模型等。

▼這麼多個模型都屬於「電子商務系統」這個context(情境、脈絡、上下文)。現在試想一個問題:開發人員如何一起合作完成這個系統?

屏幕截图 2016-11-04 14.59.29

 

看到這裡有經驗的人可能會想:這個很簡單啊,既然已經區分出這麼多個模型,就可以依據這些模型的範圍作為分配工作的邊界。假設有三個團隊一起開發這個電子商務系統:

  • 團隊1:購物模型、庫存管理模型。
  • 團隊2:產品目錄管理模型、權限管理模型。
  • 團隊3:客戶關係管理模型、帳務管理模型、物流管理模型。

到目前為止都很簡單,也都是傳統軟體開發的正規作法。在這種情況下,有一個問題必須被解決,那就是需要一個可以容納這麼多模組一起合作的軟體架構,否則整個系統最後整合起來會遇到很大的問題。當一個系統所包含的模組越多,系統架構也越發複雜。開發人員為了整合綜多模組,需要理解各別模組內部的domain model,並且要留意這些domain model和其他模組內部的domain mode是否有重複或相異之處,以增加可重用性並且避免整合時發生不相容的問題

為了保存domain model狀態系統後端需要某種儲存媒介,不管是關聯式資料庫、No-SQL或是檔案系統。在傳統的系統架構中,許多資料的整合都是透過後端的資料庫來進行(產生資料庫耦合)。例如,購物系統、庫存管理系統、產品目錄管理系統、物流管理系統,這四個系統都需要操作與修改「產品資料」。當物流管理系統出貨之後,產品庫存數量會被減1,這時候購物系統所顯示的產品可買量就少1;這就是典型「透過資料庫作為系統整合工具」的例子。

***

Bounded Context

Bounded Context在DDD中扮演非常關鍵的角色,它是分而擊之(divide and conquerdivide and conquer)的概念。bounded context的想法就是不要把一整個大系統視為一個context,而是依據「某種方式」把整個大系統分成若干個bounded context(有界限的context)。所以原本的「電子商務系統」從1個很大的context變成下圖7個bounded context。

屏幕截图 2016-11-04 15.43.30

 

每一個bounded context都有屬於自己的domain model。bounded context範圍內的dmoain model只對於自己這個範圍內有意義,不同bounded context就算有相同名稱的domain object,它們的意義可以而且通常是不需要一致。例如「庫存管理」bounded context與「購物」bounded context都有product(產品)這個領域物件(domain object),前者可能記錄著目前庫存量、最低庫存量(低於此數量需要補貨),而後者記錄可賣量、售價等。在兩個不同的bounded context中雖然都有product,但是各別的product可以有不同的屬性與行為。

屏幕截图 2016-11-04 16.00.09

***

有什麼好處

Bounded Context的概念帶來幾個重要的好處:

  • 透過通用語言減少溝通障礙:在傳統的情況下,整個專案形成一個很大的context,要求開發團隊(包含懂商業邏輯的領域專家)全部理解整個大context裡面的domain model object的意義並透過其達成溝通目的是一件很困難的事情。因此負責不同模組的人漸漸用自己熟悉的語言做為溝通工具,領域專家、專案經理、開發人員、測試人員等,各自用自己的話(術語)和別人溝通,如此一來很容易造成誤會。Bounded context的概念希望將所要解決的問題切小之後,負責這個bounded context的人都用這個bounded context的domain model為主要的溝通工具。也就是說領域專家、專案經理、開發人員、測試人員等,大家在溝通事情的時候講的是相同的術語,這個術語主要的成份就是bounded context內的domain model object。因此,在DDD中,又把bounded context內的domain model稱為Ubiquitous Language(通用語言;DDD所說的Ubiquitous Language除了domain model以外還可能包含其他東西,但語言的主幹是domain model,因此可以先把domain model看成Ubiquitous Language)。
  • Bounded context的實作形成鬆散偶合系統:Bounded context就好像一個「國家」、「經濟體」或「自治領域」,擁有自己獨立的領土、貨幣、語言、軍隊、司法系統等。每一個bounded context可以被實作成一個服務(service)或微服務(microservice),不同的bounded context之間透過訊息來交換資料,例如透過SOAP或Restful HTTP的方式形成鬆散偶合系統。
  • 技術多樣性:不同的bounded context可以採用不同的程式語言、框架、資料庫實作,例如「購物bounded context」用Java與Oracle Database Server,「庫存管理bounded context」用C#與SQL Server,「客戶關係管理bounded context」用PHP加No-SQL,「權限管理bounded context」外包XD。
  • 開發團隊與架構相匹配:一個bounded context交由一個團隊負責開發(一個團隊可開發多個bounded context),團隊內部內聚力很高,跨團隊的偶合性很低(符合高內聚、低耦合的設計原則)。不同的bounded context(團隊)之間的關係透過DDD所謂的Context Mapping來管理(日後再介紹)。
  • 和Microservice架構自然對應:Bounded context在實作上可直接對應microservice,「理論上」microservice架構對於持續交付、DevOps有很好的支持,可以加速企業提供服務的反應能力。

***

友藏內心獨白:有好處一定也有缺點。

1 則留言:

  1. Microservice 看起來比較適合網絡服務。如果是行動 App,不需要連網的,視作層面會是怎樣的情況?

    回覆刪除