2014-02-11 57 views
1

我有一個域對象圖,我需要構建一個DTO以將其發送到視圖。如何正確設計它?我看到2個選項,我可以在哪裏放置DTO構建代碼:從域對象構建DTO的設計

1)進入DTO構造函數。但是,域對象必須通過getter將所有字段顯示給DTO,所以它不是DDD。

public DTO(DomainObject domain) { 
    /// access internal fields of different domain object. 
} 

2)進入域對象。訪問字段不會有問題,但添加新視圖時,域對象將會非常快速地增長。

public DTO1 createDTO1() { 
    ... 
} 

public DTO2 createDTO1() { 
    ... 
} 

// and so on... 

我應該如何正確構建DTO?

回答

2

變種:

  1. 構造簡單類型的DTO:公共DTO(長ID,字符串標題,年整型,雙價)
  2. 單獨的類 - 轉換器等的方法:DTO1 createDTO1(domainObject的域)
  3. 框架副本屬性從一個對象到其它,例如推土機:http://dozer.sourceforge.net/
+0

ad 2.轉換器仍然需要訪問域對象的privite字段,對吧? – piotrek

+0

自定義轉換器通常無法訪問私有字段。可以使用來自1.的構造函數或DTO引用程序。 – pasha701

0

1)...的域對象必須通過干將呈現各個領域的DTO ...

2)...域對象將增長非常快...

正如你所看到的,問題是,這兩種選擇將您的模型與您的DTO耦合在一起,因此您需要將它們分開:在它們之間引入一個負責執行映射/轉換的層。

您可能會感興趣this SO question

0

領域對象通過干將呈現給DTO所有領域,所以它不是一個 DDD

僅僅因爲一個領域對象的getter並不能使貧血或抗DDD。您可以獲得行爲。

此外,由於要發佈到視圖包含特定數據的DTO,我看不到這個數據是如何保持私人域對象內。你必須以某種方式暴露它。解決方案2)打破了關注點和分層的分離(創建DTO不是域對象的業務),所以我會堅持1)或者@ pasha701的其中一個選擇。

3

我覺得在這裏玩是個大問題。你應該而不是查詢你的域名。您的域名應該專注於行爲,因此很可能不會以適合視圖的格式包含數據,尤其是出於顯示目的。

如果您要將整個對象(例如Customer)發送回Edit,那麼您正在執行基於實體的交互,這些交互非常關注數據。您可能想嘗試將更多注意力放在基於任務的交互上。

所以要獲取數據到你的視圖,我會建議一個簡單的查詢圖層。通常情況下,您需要一些非規範化數據來提高查詢性能,而且這些數據不會出現在您的域中。如果您確實需要DTO,請直接從數據源映射它們。如果你可以擺脫更通用的數據容器結構,那麼這是一等獎。