2010-10-11 8 views
18

Ich habe eine MVC2 n-Tier-Anwendung (DAL, Domain, Service, MVC-Web) mit einem DDD-Ansatz (Domain Driven Design), mit einem Domain Model mit Repositories. Meine Serviceschicht verwendet ein Request/Response-Muster, in dem die Request- und Response-Objekte DTOs (Data Transfer Objects) enthalten, um Daten von einer Schicht zur nächsten zu übertragen. Die Zuordnung erfolgt über die Hilfe von AutoMapper. Meine Frage ist diese: welche Form sollte ein DTO normalerweise nehmen? Kann es haben verschachtelt/komplex DTO ist auch oder sollte es streng eine flach Projektion? Oder möglicherweise eine Mischung aus beidem? Was sind auch die Hauptgründe dafür, ein flaches DTO gegenüber einem komplexeren/verschachtelten DTO zu haben?DTO Form: flach, komplex/verschachtelt oder eine Mischung aus beiden

Zum Beispiel: Angenommen ich eine Domain wie die folgenden hatte:

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; } 
} 

Es gibt drei verschiedene Möglichkeiten, wie ich von der Modellierung des Response-Objekt gedacht haben.

Option 1 - die trockenste Option:

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

Von der Forschung, die ich getan habe, wäre es unangemessen, für eine DTO eine ähnliche Form wie das Domain-Objekt zu übernehmen (s), wie oben gezeigt, .

Option 2 - ein abgeflachte Vorsprung der Domäne (anti-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; } 
} 

Dies ist einfacher, wie ein DTO sollte offensichtlich sein, aber letztlich für mehr DTOs macht.

Option 3 - eine Mischung aus beidem: meine Domain nicht Struktur an den Endverbraucher

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

Dies ermöglicht den Code ein wenig trocken, wiederverwendbar und überschaubar zu sein, und belichten . Der andere Hauptvorteil besteht darin, dass andere Antworten wie GetCompanyResponse einfach CompanyDTO zurückgeben können, ohne eine Kopie all dieser Eigenschaften erstellen zu müssen, ähnlich wie Option 2. Was denken Sie? Welche dieser Optionen haben Sie für sich genommen und/oder gearbeitet? Wenn diese Requests/Responses später als WCF-Service-Methoden verfügbar gemacht werden, ändert sich Ihre Antwort?

+1

Warum erstellen Sie überhaupt n-tier MVC-Anwendung? Ich sage nicht, dass es falsch ist. Nur neugierig, welchen Vorteil Sie erhalten, indem Sie Dienste zwischen Ihrem Domain-Modell und Web-Tier setzen –

+1

Ich möchte nur auf einen bestimmten Kommentar antworten, den Sie gemacht haben: "eine Kopie all dieser Eigenschaften machen". Sobald Ihr System einen bestimmten Komplexitätsschwellenwert erreicht, ist es möglicherweise besser, ein dediziertes Lesemodell zu haben, das auf DB-Ebene denormalisiert ist (entweder nach Sichten oder in Ihrer ORM-Konfiguration). Als ich damit anfing, erlaubte es mir, viel komplexere Domänenmodelle zu erstellen, weil ich mich nicht darum kümmern musste, sie für die Abfrageseite zu hydratisieren.Ich meine, warum mehrere Modelle hydratisieren, wenn Sie sie nur denormalisieren? Lass die DB das machen. Es ist trotzdem gut. – Ryan

+0

@Szymon Es gibt viele Vorteile einer Service-Tier. Für mich ist der größte Vorteil, dass ich die gesamte Sicherheit in eine Schicht legen kann und nicht in meine Controller eindringen kann. – Ryan

Antwort

11

Meine persönliche Vorliebe wäre es zu versuchen, es so flach wie möglich zu halten und nur die erforderlichen Daten zu übertragen. Ich habe gesagt, dass ich in der Vergangenheit tief verschachtelte DTO verwendet habe, weil es damals sinnvoll war und die Anforderungen erfüllte. Ich denke, es kommt darauf an "es kommt darauf an". Am Ende des Tages gehen Sie mit, was für die vorliegende Anwendung sinnvoll ist. Kein Punkt, der versucht, Horndaten in eine DTO-Konvention zu schuhen, die nicht zu dem passt, was Sie erreichen wollen.

+0

Aka - Wirf keinen gesunden Menschenverstand aus dem Fenster, nur um ein mehrdeutiges und vages Designmuster (DTOs) zu erreichen. ;) Wie speichern Sie hierarchische Informationen (Produktkategorien) in einem flachen DTO? – jfar

+0

@jfar Einer der Faktoren, die ich betrachte, ist die Fröhlichkeit der Anwendung. Wenn viel Verkehr über die Leitung fließt (dh der Kunde fordert viele kleine Teile von Informationen), um nur die eine Seite der Information anzuzeigen, würde ich versuchen, diese in einer Anfrage nach Informationen zu konsolidieren und die Daten in einem geeigneten Format zurückzugeben . –

+0

10 @jfar Wenn es der würde würde ich wahrscheinlich denormalisieren, so dass Sie die Kategorie als Teil des Produkts enthalten. Wie ich in meiner Antwort sagte, bevorzuge ich es so flach wie möglich zu halten, aber das bedeutet nicht, dass es flach wie ein Pfannkuchen sein sollte. Wenn es mit einem hierarchischen DTO einfacher ist, den Code in Ihrer Sprache zu schreiben und zu pflegen, würde ich diese Route wie in der Vergangenheit wählen, wenn ich Webservices mit MS InfoPath verwende. Der Versuch, den DTO zu verflachen, machte in diesem Fall keinen Sinn. Der Datenbedarf der Anwendung definiert das DTO. –