領域知識與模型 - 服務

領域模型主要由實體所組成,除了封裝物件資訊的屬性成員,同時擁有專屬的功能行為,以支援特定的領域問題處理,而通常領域問題不會這麼簡單,我們需要很多跨物件功能的設計,因此必須建立獨立的共用物件,以封裝這些功能,提供需要的物件共用,這一類的物件我們將其視為服務物件,提供處理領域實體共同問題所需的服務。

考慮庫存管理應用,我們在資料庫儲存商品的庫存數量,並且撰寫功能物件,支援庫存量的異動。

在很多情形下,系統會需要處理庫存量的異動,例如商品採購完成確認入庫時,應用程式必須根據入庫的數量增加庫存量,如果是客戶訂單完成交易,則需根據訂購數量,減少庫存量,其它的狀況,還有如商品盤點作業等等。



「庫存數量調整」設計成獨立功能物件,如此一來,其它的實體都可以同時使用這個功能物件,並以服務的型式提供,對於這種多實體的共用功能,並不適合配置於特定的物件中,當其它實體需要使用此服務時,將導致物件彼此的不當引用。



上圖另外配置一個商品實體,庫存量調整後的商品數量,最後將反映至商品實體的庫存量記錄,是與Product密切相關的功能,在設計上,若是將功能配置於Product實體,將導致實體之間的耦合,如下圖所示。



與實體不同的地方,在於服務物件純粹提供功能由其它的實體取用,本身並不負責任何領域實體的資訊或是狀態維護,而在實際的開發中,我們會大量撰寫功能物件,提供實體所需的服務,儘量單純化實體設計。

服務由各種功能物件組成,物件彼此間會進一步協同運作,與實體設計隔離開來,並且協調處理實體之間的流程運作,更進一步降低實體彼此間的耦合,這個過程中,我們透過建立服務介面來支援相關的實作,透過相依性注入,避免功能物件的直接取用。
相依性注入的相關實作與應用請參考實體書《商業級 ASP.NET MVC 樣式與架構實務》。

最後還有一點要注意的,服務本身並不維護任何物件的狀態資訊,這些資訊應該要附屬於關聯實體。

服務與分層架構

服務完成某項操作,這個操作可能牽涉數個實體,或是其功能可能作為流程轉向控制,因此服務功能物件的配置,相較於實體或實值物件,可能出現在服務層或是領域層,參考分層設計教學文中所討論的,如果服務本身為實體分離出來負責提供特定功能的取用,則需要配置於領域層,而負責流程協調運作的相關服務,則配置於應用層。






沒有留言: