我不確定爲此使用服務。
據我所知,DDD的原理之一(我現在正在閱讀)是域對象組織成聚合,並且當你創建一個聚合根的實例時,它可以只能直接處理Aggregate中的對象(以幫助保持清晰的責任感)。
創建骨料應該執行任何不變量等
隔空Customer類的一個例子,客戶可能是聚合根和骨料內的另一個類可能是地址。
現在,如果您要創建新的客戶,您應該可以使用客戶構造函數或工廠來完成此操作。這樣做應該返回在Aggregate邊界內完全有效的對象(所以它不能處理產品,因爲它們不是Aggregate的一部分,但它可以處理地址)。
數據庫是一個次要問題,只有將聚合持久化到數據庫或從數據庫中檢索數據庫時才起作用。
爲了避免直接與數據庫連接,您可以創建一個Repository接口(如上所述),給定一個Customer實例(其中包含對Address的引用)應該能夠將Aggregate持久化到數據庫。
問題是,Repository接口是你的領域模型/層的一部分(不是庫的實現)。另一個因素是版本庫可能最終應該調用與創建新對象相同的「創建」方法(以維護不變量等)。如果你使用的是構造函數,這很簡單,因爲當數據庫從數據庫「創建」對象時,最終你會調用構造函數。
應用程序層可以直接與域(包括存儲庫接口)進行通信。
所以,如果你想創建一個對象的新實例,你可以例如
Customer customer = new Customer();
如果應用程序需要檢索庫中的客戶的實例,也沒有特別的原因,我能想到的它不叫......
Customer customer = _custRepository.GetById(1)
或...
Customer customer = _custRepository.GetByKey("AlanSmith1")
最終,它將最終得到一個Customer對象的實例,它在它自己的限制和規則內運行,就像直接創建新的Customer對象一樣。
我認爲服務應該保留,當你試圖使用的「東西」只是不是一個對象。大多數規則(約束等)可以寫成域對象本身的一部分。
一個很好的例子是在我正在閱讀的DDD快速pdf。在那裏,他們對書架對象有一個限制,因此只能添加與書架可以包含的書一樣多的書。
調用BookShelf對象上的AddBook方法會在將書籍添加到BookShelf的Book對象集合之前檢查該空間是否可用。一個簡單的例子,但業務規則是由域對象本身強制執行的。
我不是說以上任何一種都是正確的!我正試圖讓我的頭在這一刻!
同意。作爲一個例子,我認爲它是「OK」,但如果他們提到這不是從架構的角度來看最好的做法,那將會很好。 – 2009-07-30 02:05:56