2009-11-24 51 views
11

在花了幾個月的時間研究DDD方法論之後,我現在開始將這些概念應用到我公司的實際產品中。事實上,我一直致力於爲未來的發展創建合適的可維護體系結構。N層開發中的DDD概念

我們已經決定利用以下技術:EF4(真V2),統一

我獲得一直是最有啓發性的信息量,不過,我留下了最好的幾個問題做法:

問題1:的DTO - 最佳實踐

我有我的域對象(PO​​CO類)。有幾種方法來實現這些類。

  1. 傳統方法:創建包含公共getter/setter方法,驗證,&相應的業務邏輯POCO類。還要創建DTO並使用映射技術來管理它們。 (Automapper)
  2. 傳統 - DTO:創建POCO類如上所述,但是,使用您的POCO作爲傳輸對象。我的理解是,業務對象不應該離開域。
  3. 混合:我偶然發現了一個有趣的blog post,其中作者創建了他的POCO對象和DTO。在他的域對象內部,他創建了DTO的一個實例。這樣可以更容易維護,因爲您不像#1那樣複製屬性。像這樣:
 
public abstract class POCOBase<T> : ValidationBase, IPOCO where T : DTOBase, new() 
{ 

public T Data { get; set; } 

public POCOBase() 
{ 
    Data = new T(); 
} 

public POCOBase(T dto) 
{ 
    Data = dto; 
} 
    } 

    public class SomePOCO : POCOBase { } 

    public class SomeDTO : DTOBase 

    { 

public String Name { get; set; } 

public String Description { get; set; } 

public Boolean IsEnabled { get; set; } 
} 


// EXAMPLES 
// POCOBase<SomeDTO> somePOCO = new SomePOCO(); 
// somePOCO.Data.Name = "blablabla"; 
// somePOCO.Validate(); 
// return somePOCO.Data; 

問題2:哪些對象應該由UI /服務層被退回?

這是DTO的重點。一個非常簡單,輕量級的對象,只包含裸露的屬性。它也不包含任何驗證結果。如果我將我的DTO序列化回客戶端,則應該假定客戶端需要任何驗證結果,如InvalidRules集合。例如,假設我正在與亞馬遜的API合作。我想添加一本書到我的個人商店。如果我嘗試添加圖書而未發送ISBN,該服務可能會返回某種包含驗證結果錯誤的響應組。

我錯過了什麼嗎?我的印象是(至少從DDD「純粹主義者」),DTOs不應該包含商業邏輯。在我看來,DTO不能提供足夠的信息作爲傳輸對象。無論是那個還是我需要一個封裝了DTO和驗證結果的新類型的Response對象。

問題3:IoC有多少?

這似乎明顯,我認爲我應該遵循的金科玉律:

「找出變化的應用 的部分,並從這些 是保持不變分開。「

對我來說,這是有道理的申請的IoC方面。爲了減少依賴,我的介紹,業務邏輯和數據訪問層通過一個IoC容器中的所有通信。在我的應用層包含通用接口和抽象,似乎我喜歡這個事實,我可以創建模擬測試存儲庫 - 通過簡單地改變Unity的配置,我可以利用TDD。

我希望我已經清楚地說明了這些問題。爲您提前提供幫助!

+2

未來,請將每個問題陳述爲單獨的StackOverflow問題... – 2009-11-25 08:57:31

回答

18

我會盡力一次解決您的問題

回答1個

DTO的正交DDD,因爲他們在應用程序的架構不同的地方用於不同的目的。也就是說,DTO在領域模型中沒有地位,因爲他們沒有行爲,因此會導致Anemic Domain Models

持久性無知的POCO是要走的路。傑里米米勒有很好的article that explains this concept

答案2

層坐域模型的頂部往往需要返回所定製的有問題的目的,自己的對象。

對於用戶界面,MVVM模式效果特別好。 This article爲WPF引入了MVVM,但該模式也像ASP.NET MVC中的魅力一樣工作。

對於Web服務,這是DTO模式適用的地方。 WCF數據合同是DTO,如果您想知道:)

這需要大量映射在服務接口和域模型之間來回切換,但這是您必須爲柔性設計支付的價格。您可能會發現AutoMapper在這方面很有幫助。

答案3

更IOC(真:DI)更好,但有一點你的問題讓我吃驚:一個DI容器只能線了對象圖,然後讓開了路。對象不應該依賴DI容器。

有關更多詳細信息,請參閱this SO answer

+0

感謝您的評論Mark。 我的理解是,當域對象無任何業務邏輯時,會出現貧血域模型。他們仍然是一羣獲得者/制定者。 ADM的另一點是邏輯(如驗證)發生在對象之外而不是包含在內。 如果你回頭看問題#1的混合方法......對我來說,在一個持續的無知域對象中創建一個DTO實例,並不一定構成一個貧血域模型。你說得對,因爲它打破了DDD的原則。我可能不得不深入探討這一點。 – Daniel 2009-11-25 12:56:23

+0

答案2是完美的。我有一個傾向,我可能需要創建自定義返回對象。感謝您對MVVM的建議......肯定會看一看。 – Daniel 2009-11-25 13:00:38

+0

我目前在我的ASP.NET web.config中配置我的DI容器,然後使用Global.asax進行設置。 對於你的答案3,如果我正確理解你的話: 那麼爲了實現TDD方法,我應該簡單地在方法本身「即時」註冊DI配置? – Daniel 2009-11-25 13:23:11