it-swarm.com.de

Was ist der Unterschied zwischen den Mustern Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) und Repository?

Ich versuche, meine Gestaltungsmusterfähigkeiten auf den neuesten Stand zu bringen, und bin gespannt, welche Unterschiede zwischen diesen Mustern bestehen? Alle scheinen das gleiche zu sein - kapseln Sie die Datenbanklogik für eine bestimmte Entität ein, sodass der aufrufende Code keine Kenntnis über die zugrunde liegende Persistenzschicht hat. In meiner kurzen Recherche implementieren alle normalerweise Ihre CRUD-Standardmethoden und abstrahieren die datenbankspezifischen Details.

Abgesehen von Namenskonventionen (z. B. CustomerMapper vs. CustomerDAO vs. CustomerGateway vs. CustomerRepository), wo liegt der Unterschied? Wenn es einen Unterschied gibt, wann würden Sie sich für eines entscheiden?

In der Vergangenheit würde ich Code schreiben, der dem folgenden ähnelt (natürlich vereinfacht - normalerweise würde ich keine öffentlichen Eigenschaften verwenden):

public class Customer
{
    public long ID;
    public string FirstName;
    public string LastName;
    public string CompanyName;
}

public interface ICustomerGateway
{
    IList<Customer> GetAll();
    Customer GetCustomerByID(long id);
    bool AddNewCustomer(Customer customer);
    bool UpdateCustomer(Customer customer);
    bool DeleteCustomer(long id);
}

und haben eine CustomerGateway-Klasse, die die spezifische Datenbanklogik für alle Methoden implementiert. Manchmal würde ich keine Schnittstelle verwenden und alle Methoden auf dem CustomerGateway statisch machen (ich weiß, ich weiß, das macht es weniger testbar), so dass ich es so nennen kann:

Customer cust = CustomerGateway.GetCustomerByID(42);

Dies scheint das gleiche Prinzip für die Data Mapper- und Repository-Muster zu sein. Das DAO-Muster (das ist dasselbe wie Gateway, denke ich?) scheint auch datenbankspezifische Gateways zu fördern.

Fehlt mir etwas? Es scheint ein bisschen komisch, 3-4 verschiedene Arten zu haben, genau dieselbe Sache zu machen.

126
Wayne Molina

Ihre Beispielausdrücke; DataMapper, DAO, DataTableGateway und Repository haben alle einen ähnlichen Zweck (wenn ich einen benutze, erwarte ich, dass sie ein Customer-Objekt zurückerhalten), jedoch unterschiedliche Absichten und Bedeutungen sowie die daraus resultierende Implementierung.

Ein Repository _ ​​"verhält sich wie eine Sammlung, außer mit komplizierteren Abfragemöglichkeiten" [ Evans, Domain Driven Design ] und kann als "- Objekte in der Speicherfassade betrachtet werden " ( Repository-Diskussion )

Ein DataMapper _ ​​"verschiebt Daten zwischen Objekten und einer Datenbank, wobei sie unabhängig voneinander und vom Mapper selbst bleiben" ( Fowler, PoEAA, Mapper )

Ein TableDataGateway ist "Ein Gateway (Objekt, das den Zugriff auf ein externes System oder eine externe Ressource enthält)) auf eine Datenbanktabelle. Eine Instanz behandelt alle Zeilen in der Tabelle" ( Fowler, PoEAA, TableDataGateway )

Ein DAO _ ​​"trennt die Clientschnittstelle einer Datenressource von ihren Datenzugriffsmechanismen/passt die Zugriffs-API einer bestimmten Datenressource an eine generische Clientschnittstelle an", wodurch "Datenzugriffsmechanismen geändert werden können) unabhängig vom Code, der die Daten verwendet " ( Sun Blueprints )

Das Repository scheint sehr allgemein zu sein und lässt keine Ahnung von Datenbankinteraktionen erkennen. Ein DAO bietet eine Schnittstelle, die die Verwendung verschiedener zugrunde liegender Datenbankimplementierungen ermöglicht. Ein TableDataGateway ist insbesondere ein dünner Wrapper um einen einzelnen Tisch. Ein DataMapper fungiert als Vermittler, damit sich das Model-Objekt unabhängig von der Datenbankdarstellung (über die Zeit) entwickeln kann.

95
Pierce Hickey

In der Welt des Software-Designs gibt es eine Tendenz (zumindest fühle ich mich so), neue Namen für bekannte alte Dinge und Muster zu erfinden. Und wenn wir ein neues Paradigma haben (das sich vielleicht etwas von bereits existierenden Dingen unterscheidet), dann enthält es normalerweise eine ganze Reihe neuer Namen für jede Stufe. So wird "Business Logic" zu "Services Layer", nur weil wir sagen, wir machen SOA, und DAO wird zu Repository, nur weil wir sagen, wir machen DDD (und jeder von ihnen ist nicht wirklich etwas Neues und Einzigartiges, aber wieder: neue Namen für bereits bekannte Konzepte, die in demselben Buch zusammengefasst sind). Ich sage also nicht, dass all diese modernen Paradigmen und Akronyme genau das gleiche bedeuten, aber Sie sollten nicht zu paranoid sein. Meistens sind dies die gleichen Muster, nur aus verschiedenen Familien.

26
Dmitry Perets

Data Mapper vs. Table Data Gateway Um es kurz zu machen:

  • der Data Mapper empfängt das Domain Model-Objekt (Entity) als Parameter und verwendet es zur Implementierung der CRUD-Vorgänge
  • das Table Data Gateway empfängt alle Parameter (als Primitive) für die Methoden und weiß nichts über das Domänenmodellobjekt (Entity).

    Am Ende fungieren beide als Vermittler zwischen den In-Memory-Objekten und der Datenbank.

  • 25
    danidacar

    Du hast einen guten Punkt. Wählen Sie diejenige aus, mit der Sie am besten vertraut sind. Ich möchte auf einige Dinge hinweisen, die zur Klärung beitragen können.

    Das Table Data Gateway wird hauptsächlich für eine einzelne Tabelle oder Sicht verwendet. Es enthält alle Auswahlmöglichkeiten, Einfügungen, Aktualisierungen und Löschungen. Der Kunde ist also eine Tabelle oder eine Ansicht in Ihrem Fall. Eine Instanz eines Tabellendatengatewayobjekts behandelt also alle Zeilen in der Tabelle. Normalerweise bezieht sich dies auf ein Objekt pro Datenbanktabelle.

    Data Mapper ist zwar unabhängiger von jeder Domänenlogik und ist weniger gekoppelt (obwohl ich glaube, dass entweder eine Kopplung vorhanden ist oder nicht). Es handelt sich lediglich um eine Zwischenschicht, um die Daten zwischen Objekten und einer Datenbank zu übertragen, wobei sie voneinander und vom Mapper selbst unabhängig bleiben. 

    In der Regel sehen Sie in einem Mapper Methoden wie Einfügen, Aktualisieren, Löschen, und in Table Data Gateway finden Sie getcustomerbyId, getcustomerbyName usw.

    Das Datenübertragungsobjekt unterscheidet sich von den obigen zwei Mustern, hauptsächlich weil es sich um ein Verteilungsmuster handelt und nicht um ein Datenquellenmuster wie über zwei Mustern. Verwenden Sie es hauptsächlich, wenn Sie mit der Remote-Schnittstelle arbeiten und Ihre Anrufe weniger gesprächig machen müssen, da jeder Anruf teuer werden kann. Entwerfen Sie daher in der Regel ein DTO, das über Kabel serialisiert werden kann und alle Daten zum Server zurückführen kann, um weitere Geschäftsregeln anzuwenden oder zu verarbeiten.

    Ich kenne mich mit dem Repository-Muster nicht aus, da ich bisher keine Chance hatte, sie zu verwenden, aber ich werde mir die Antworten anderer anschauen. 

    15
    Srikar Doddi

    Unten ist nur mein Verständnis.

    TableGateWay/RowDataGateWay : .__ In diesem Zusammenhang verweist Gateway auf eine bestimmte Implementierung, in der jedes "Domänenobjekt" für jedes "Domänenobjekt-Gateway" zugeordnet ist. Wenn wir beispielsweise Person haben, haben wir ein PersonGateway, um das Domänenobjekt Person in der Datenbank zu speichern. Wenn wir Person, Mitarbeiter, Kunde usw. haben, haben wir PersonGateway, EmployeeGateway und CustomerGateway. Jedes Gateway verfügt über eine spezifische CRUD-Funktion für dieses Objekt und hat nichts mit dem anderen Gateway zu tun. Es gibt hier keinen wiederverwendbaren Code/Modul. Das Gateway kann weiter in RowDataGateway oder TableGateway unterteilt werden, abhängig davon, ob Sie eine "ID" oder ein "Objekt" übergeben. Gateway wird normalerweise mit Active Record verglichen. Es bindet Ihr Domänenmodell an ein Datenbankschema.

    Repository/DataMapper/DAO : Sie sind dasselbe. Sie beziehen sich alle auf die Persistence-Schicht, die Datenbankentitäten in das Domänenmodell überträgt. Im Gegensatz zum Gateway verbergen die Repository/DataMapper/DAO die Implementierung. Sie wissen nicht, ob sich hinter Person ein PersonGateway befindet. Vielleicht ist es Ihnen egal oder nicht. Sie wissen nur, dass CRUD-Vorgänge für jedes Domänenobjekt unterstützt werden müssen. Es entkoppelt die Datenquelle und das Domänenmodell.

    0
    Hao Lu