2010-10-11 51 views
18

我有一個MVC2 n層應用程序(DAL,域,服務,MVC網絡)使用DDD方法(域驅動設計)庫。我的服務層使用請求/響應模式,其中請求和響應對象包含DTO(數據傳輸對象)以將數據從一層封送到下一層,並且映射通過AutoMapper的幫助完成。我的問題是這樣的:DTO通常採用什麼形狀?它可以有嵌套/複雜 DTO的也應該嚴格是平面投影? 或者可能是兩者的混合?另外,有一個扁平的DTO與一個更復雜/嵌套的DTO的主要原因是什麼?DTO形狀:平坦,複雜/嵌套或兩者的混合

舉例來說,假設我有一個域名,如以下幾點:

public class Employee 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Company Company { get; set; } 
} 
public class Company 
{ 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
} 

有三種不同的方式,我覺得造型Response對象。

選項1 - 在DRYest選項:

public class GetEmployeeResponse 
{ 
    public class EmployeeDTO { get; set; } // contains a CompanyDTO property 
} 

從研究,我已經做了,這將是不適當的DTO採取類似的形狀域對象(S)如上文所示。

選項2 - 域(抗DRY)的扁平的投影:

public class GetEmployeeResponse 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string CompanyName { get; set; } 
    public string CompanyAddress { get; set; } 
    public string CompanyCity { get; set; } 
    public string CompanyState { get; set; } 
} 

這是更簡單,像一個顯然DTO應,但最終使更多的DTO。

選項3 - 兩者的混合物:

public class GetEmployeeResponse 
{ 
    public EmployeeDTO Employee { get; set; } 
    public CompanyDTO Company { get; set; } 
} 

這允許代碼是一點點更幹,可重複使用的和可管理的,並且不暴露我域結構到最終用戶。另一個主要的好處是,其他的迴應,如GetCompanyResponse可以簡單地返回CompanyDTO,而不必複製所有這些屬性,類似於選項2.你怎麼看?這些(如果有的話)您選擇了哪些選項和/或爲您工作過?如果這些請求/響應稍後作爲WCF服務方法公開,那麼您的答案是否會更改?

+1

爲什麼你首先建立n層MVC應用程序?我不是說這是錯的。只是好奇你在域模型和網絡層之間提供服務所帶來的好處 – 2010-10-12 05:06:19

+1

我只想回應你提出的具體評論:「製作所有這些屬性的副本」。一旦系統達到一定的複雜度閾值,最好在DB級別有一個非規範化的專用讀取模型(通過視圖或ORM配置)。當我開始這樣做時,它允許我構建更復雜的領域模型,因爲我不必擔心爲事物的查詢方提供保溼的費用。我的意思是,爲什麼要保護多個模型,如果你只是要使它們非規範化?讓DB做到這一點。無論如何它都是好的。 – Ryan 2010-10-12 05:07:50

+0

@Szymon有一個服務層的優點很多。對我來說,最大的好處是我可以把所有的安全性放在一個層中,而不是讓它泄漏到我的控制器中。 – Ryan 2010-10-12 05:09:29

回答

11

我的個人偏好是儘可能保持平坦,只需要傳輸所需的數據。說過我在過去使用了深度嵌套的DTO,因爲它在當時是有意義的,並符合要求。所以我想這歸結於「取決於」。在一天結束的時候,請按照手頭應用程序的意義進行操作。嘗試將喇叭數據轉換成不符合你想要實現的DTO慣例是沒有意義的。

+0

Aka - 不要爲了達到模糊和模糊的設計模式(DTO)而將常識拋出窗外。 ;)如何在平面DTO中存儲層次信息(產品類別)? – jfar 2010-10-12 03:26:26

+0

@jfar我看到的一個因素是應用程序的煩躁。如果網絡上有很多流量(即客戶端請求很多小信息)只是爲了顯示一頁信息,我會考慮將它合併爲一個信息請求並以適合的格式返回數據。 – 2010-10-12 22:23:42

+0

@jfar如果它適合我​​可能denormalise,以便您將該類別作爲產品的一部分。正如我在答覆中所說的,我寧願保持它儘可能平坦,但這並不意味着它應該像扁餅一樣平坦。如果有一個heirarchial DTO使得eaiser能夠以您選擇的語言編寫和維護代碼,那麼我將選擇使用MS InfoPath的web服務時的路線。試圖壓平DTO在這種情況下沒有意義。應用程序的數據需求定義了DTO。 – 2010-10-12 22:37:48