2009-09-06 25 views
12

Ich erwäge, DTOs zu verwenden, anstatt meine Domäne-Objekte herumzugeben. Ich habe hier und auch anderswo mehrere Beiträge gelesen, und ich verstehe, dass es mehrere Ansätze gibt, dies zu erreichen.DTOs: Best Practices

Wenn ich insgesamt nur etwa 10 Domänenklassen habe und in Betracht ziehe, dass ich DTOs anstelle von Domänenobjekten für den Verbrauch in meinen Ansichten (WPF-Frontends) verwenden möchte, was ist der empfohlene Ansatz. Ich denke, mit Tools wie Auto-Mapper etc. ein Overkill für meine Situation. Also denke ich daran, meine eigene Mapper-Klasse zu schreiben, die Methoden zum Konvertieren eines Domain-Typs in einen DTO-Typ haben wird.

Was ist der beste Weg, dies zu tun, gibt es eine Probe, um mich dazu zu bringen, dies zu tun?

Zweite Frage: Wie schreibe ich beim Erstellen dieser Methoden, die DTOs erstellen, mit der Einrichtung aller Daten, insbesondere wenn der Domain-Typ Verweise auf andere Domain-Objekte hat? Schreib ich äquivalente Eigenschaften im DTO für die Zuordnung zu diesen Reference-Typen in der Domain-Klasse? Bitte fragen Sie, wenn ich meine zweite Frage nicht in richtige Worte gestellt habe. Aber ich denke du verstehst was ich versuche zu fragen.

Frage: Wenn ich DTOs schreibe, sollte ich mehrere DTOs schreiben, die jeweils Teildaten für ein bestimmtes Domänenmodell enthalten, so dass jedes davon verwendet werden kann, um eine bestimmte View-Anforderung zu erfüllen, oder sollte der DTO alle haben Daten, die in der entsprechenden Modellklasse vorhanden sind.

+0

auch bereit sein, Schreiben Sie mehrere spezifische Datenübertragungsobjekte für bestimmte Servicemethoden, nicht nur für eine bestimmte Domäne M Marken. – Lightman

Antwort

0

Ich gehe davon aus, dass Ihre Domänenmodellobjekte eine Primärschlüssel-ID haben, die den IDs aus der Datenbank oder dem Speicher entsprechen kann, aus dem sie stammen.

Wenn das Obige wahr ist, wird Ihr DTO den Typ, der auf andere DTOs verweist, wie Ihre Domänenobjekte, in Form einer Fremdschlüssel-ID überwinden. Eine OrderLine.OrderHeader-Beziehung für das Domänenobjekt ist also OrderLine.OrderHeaderId im DTO.

Hoffe, dass hilft.

Kann ich fragen, warum Sie DTO anstelle Ihrer Rich-Domain-Objekte in der Ansicht verwendet haben?

+1

Können die DTOs ID-Eigenschaften in ihnen haben? - d. h. OrderlineID in Ihrer Stichprobe. Ich dachte, dass DTOs vollständig eigenständige Datenobjekte sind, die keinen Bezug zur Datenbank und anderen externen Abhängigkeiten haben. Was DTOs angeht, wird sich mein Projekt in Zukunft zu einem großen System entwickeln, und ich möchte sicherstellen, dass ich es jetzt so erstelle, dass ich in Zukunft Daten über Web-Service-Anfragen offenlegen kann. Beter, gute Praxis vom Tag 0 zu folgen nehme ich an. Haben Sie eine Idee für meine dritte Frage (die ich nur ein paar Minuten zurückgelegt habe). –

3

Ich verwende irgendwie DTOs in einem Projekt. Ich tendiere dazu, die DTOs nur dazu zu bringen, die Daten anzuzeigen, die ich für eine bestimmte Ansicht benötige. Ich hole alle in der Ansicht angezeigten Daten in meiner Datenzugriffsklasse. Zum Beispiel kann ich ein Order-Objekt haben, die eine Client-Objekt verweist:

public class OrderListDTO{ 
    public int OrderId{get;set;} 
    public string ClientName{get;set;} 
    ... 
} 

Welche Felder sind ich in meiner Sicht zeigen wollen:

public class Client{ 
    public int Id{get;set;} 
    public string Name{get;set;} 
} 

public class Order{ 
    public int OrderID{get;set;} 
    public Client client{get;set;} 
    public double Total{get;set;} 
    public IEnumerable<OrderLine> lines {get;set;} 
} 

Da ist in meinem OrderListDTO ich so etwas haben kann . Ich hole alle diese Felder in meinem Datenbankzugriffscode, damit ich mich nicht mit Entitäten in meiner Sicht oder dem Controller-Code befassen muss.

+0

Wie behandeln Sie die Eigenschaft "Linien" in Ihren DTO-Objekten? Machst du OrderListDTO flach oder lädst du die "Linien" Sammlung wie? –

+0

Hängt vom Kontext ab. Wenn ich die Zeilen in der Ansicht brauche, lade ich sie; wenn nicht, ich nicht. Manchmal habe ich vielleicht eine LineCount Eigenschaft auf meiner OrderListDTO und ich mache LineCount = order.lines.Count() oder ich zeige eine Summe: LineSum = order.lines.Sum (t => t.Quantity) ... –

5

Ich habe hier ein paar Posts über DTO's gelesen und es scheint mir, dass viele Leute sie gleichsetzen mit dem, was ich als ViewModel ansehen würde. Ein DTO ist genau das, Data Transfer Object - es wird übertragen. Ich habe also eine Website und Dienste, nur die Dienste haben Zugriff auf reale Domänen-/Entitätsobjekte und geben DTOs zurück. Diese können 1: 1 zugeordnet werden, aber bedenken Sie, dass die DTOs von einem anderen Serviceaufruf, einer Datenbankabfrage, einer Konfigurationsdatei - was auch immer - aufgefüllt werden können.

Danach kann die Website dann diese DTO nehmen und sie entweder zu einem ViewModel hinzufügen, oder in eins umwandeln. Dieses ViewModel kann viele verschiedene Arten von DTOs enthalten.Ein einfaches Beispiel wäre ein Task-Manager - das ViewModel enthält sowohl das Task-Objekt, das Sie bearbeiten, als auch eine Gruppe von Dto.User-Objekten, denen die Task zugewiesen werden kann.

Beachten Sie, dass die Dienste, die DTOs zurückgeben, möglicherweise sowohl von einer Website als auch von einem Tablet oder einer Telefonanwendung verwendet werden. Diese Anwendungen würden unterschiedliche Ansichten haben, um ihre Anzeigen zu nutzen, und so würden sich die ViewModels unterscheiden, aber die DTOs würden gleich bleiben.

Jedenfalls liebe ich diese Art von Diskussionen, also lassen Sie mich bitte wissen, was Sie denken.

Matt

+0

Nur um Ein DTO ist kein ViewModel. Es ist kein DisplayModel, sondern ein TransferModel-Agnostiker der Benutzeroberfläche. Noch mehr, wenn Sie REST-Services zum Übertragen von DTOs ausführen, sollten sie nichts von der UI-Struktur wissen. – Elisabeth

1

ich komme mit spring-jdbc zu projizieren und es werden DAO Schicht verwendet. Einige Male bestehende Entitäten decken nicht alle möglichen Daten von DB ab. Also fange ich an, DTO zu verwenden.

von '70 Struktur Programmierung Regel Anwendung habe ich alle DTOs in separates Paket:

package com.evil.dao;  // DAO interfaces for IOC. 
package com.evil.dao.impl; // DAO implementation classes. 
package com.evil.dao.dto; // DTOs 

Jetzt habe ich überdenken und entscheiden, alle DTO als innere Klassen auf DAO-Schnittstellen für Ergebnis-Sets zu setzen, die keine Wiederverwendung haben. So DAO-Schnittstelle wie folgt aussehen:

interface StatisticDao { 
    class StatisticDto { 
     int count; 
     double amount; 
     String type; 

     public static void extract(ResultSet rs, StatisticDto dto) { ... } 
    } 

    List<StatisticDto> getStatistic(Criteria criteria); 
} 


class StatisticDaoImpl implements StatisticDao { 
    List<StatisticDto> getStatistic(Criteria criteria) { 
     ... 
     RowCallbackHandler callback = new RowCallbackHandler() { 
      @Override 
      public void processRow(ResultSet rs) throws SQLException { 
       StatisticDao.StatisticDto.extract(rs, dto); 
       // make action on dto 
      } 
     } 
     namedTemplate.query(query, queryParams, callback); 
    } 
} 

denke ich, dass Daten zusammen im Zusammenhang Holding (benutzerdefinierte DTO mit DAO-Schnittstelle) machen Code besser für PageUp/PageDown.

0

bester Weg DTOs

Die Art und Weise zu entwickeln, die Entwicklung DTOs zu beginnen, ist zu verstehen, dass ihr einziger Zweck Teilmenge der Daten Ihrer Geschäftseinheiten zu verschiedenen Clients zu übertragen ist (könnte UI oder ein externer Dienstleister sein). Mit diesem Verständnis könnten Sie separate Pakete für jeden Client erstellen ... und Ihre DTO-Klassen schreiben. Für die Zuordnung könnten Sie einen eigenen Mapper schreiben, der Schnittstellen definiert, die an eine Fabrik übergeben werden, die DTO-Objekte erstellt, basierend darauf, welche Daten aus der Entität extrahiert werden, für die der DTO erstellt wird. Sie könnten auch Annotationen definieren, die in Ihren Entitätsfeldern platziert werden, aber persönlich die Anzahl der verwendeten Annotationen bevorzugen, würde ich die Schnittstelle bevorzugen. Die wichtigste Anmerkung zu DTOs ist, dass sie auch Klassen sind und Daten unter den DTOs wiederverwendet werden sollen. Mit anderen Worten, es mag verlockend sein, DTOs für jeden Anwendungsfall zu erstellen, versuchen Sie, vorhandene DTOs wiederzuverwenden, um dies zu minimieren.

Erste Schritte

In Bezug Sie beginnen, wie oben dem alleinigen Zweck der DTO angegeben ist dem Kunden die Daten, die er braucht, zu geben .... so dass Sie im Auge behalten konnte gerade eingestellten Daten in den dto mit Setter ... oder eine Fabrik definieren, die ..... basiert auf einer Schnittstelle ein DTO von einer Entität erstellt

In Bezug auf Ihre dritte Frage tun, wie von Ihrem Client erforderlich ist :)