it-swarm-eu.dev

Ist "Mapper" ein gültiges Entwurfsmuster oder eine Variation des "Factory" -Musters?

Ein häufiges Muster, das ich sehe, ist das sogenannte Mapper Muster (nicht zu verwechseln mit DataMapper, das etwas ganz anderes ist), das als Argument eine Art "rohe" Datenquelle verwendet ( zB ein ADO.NET DataReader oder DataSet) und ordnet die Felder Eigenschaften eines Geschäfts-/Domänenobjekts zu. Beispiel:

class PersonMapper
{
    public Person Map(DataSet ds)
    {
        Person p = new Person();
        p.FirstName = ds.Tables[0].Rows[0]["FirstName"].ToString();
        // other properties...
        return p;
    }
}

Die Idee ist Ihr Gateway/DAO/Repository/etc. ruft den Mapper auf, bevor er zurückkehrt, sodass Sie ein umfangreiches Geschäftsobjekt im Vergleich zum zugrunde liegenden Datencontainer erhalten.

Dies scheint jedoch mit dem Factory-Muster (im DDD-Sprachgebrauch jedenfalls) zu zusammenhängen, das ein Domänenobjekt erstellt und zurückgibt, wenn nicht sogar identisch. Wikipedia sagt dies bezüglich der DDD-Fabrik:

Factory : Methoden zum Erstellen von Domänenobjekten sollten an ein spezielles Factory-Objekt delegiert werden, damit alternative Implementierungen leicht ausgetauscht werden können.

Aus diesem Zitat kann ich mir nur vorstellen, dass die Factory im DDD-Stil so parametrisiert werden kann, dass sie bei Bedarf einen speziellen Objekttyp zurückgibt (z. B. BusinessCustomer oder ResidentialCustomer), während der "Mapper" für eine bestimmte Klasse verschlüsselt ist und nur übersetzt.

Gibt es also einen Unterschied zwischen diesen beiden Mustern oder sind sie im Wesentlichen dasselbe mit unterschiedlichen Namen?

37
Wayne Molina

Obwohl ich zum ersten Mal von dem Mapper-Muster höre, klingt es für mich eher nach dem Builder-Muster als nach der Factory.

Im Factory-Muster kapseln Sie die Logik zum Erstellen von Objekten einer Reihe verwandter Klassen. Das beste Beispiel wäre eine Situation, in der Sie abhängig von einigen Parametern ein Objekt einer bestimmten Unterklasse einer abstrakten Basisklasse erstellen müssen. Eine Factory gibt also immer einen Zeiger oder eine Referenz auf die Basisklasse zurück, erstellt jedoch tatsächlich ein Objekt der entsprechenden abgeleiteten Klasse basierend auf den von Ihnen angegebenen Parametern.

Im Gegensatz dazu erstellt eine Builder-Klasse immer Objekte derselben Klasse. Sie würden es verwenden, wenn die Erstellung eines Objekts kompliziert ist, z. G. Der Konstruktor verwendet viele Argumente, von denen möglicherweise nicht alle sofort verfügbar sind. Ein Builder-Objekt kann also ein Ort sein, an dem die Werte für die Konstruktorargumente gespeichert werden, bis Sie alle haben und bereit sind, das "Produkt" zu erstellen, oder es kann vernünftige Standardwerte bereitstellen und Sie können nur die Argumente angeben, deren Werte Sie benötigen Veränderung. Ein typischer Anwendungsfall für das Builder-Muster ist das Erstellen von Objekten, die Sie möglicherweise in einem Komponententest benötigen, um zu vermeiden, dass der Testcode mit der gesamten Erstellungslogik überladen wird.

Für mich klingt ein Mapper wie eine Variante eines Builders, bei der die Konstruktorparameter in Form eines Datenbankdatensatzes oder einer anderen "Roh" -Datenstruktur vorliegen.

23
Dima

Das einzig Gemeinsame an Mapper, Builder und Factory ist, dass sie ein "konstruiertes Produkt" liefern - und eine Objektinstanz eines Typs. Um Verwirrung zu vermeiden, beziehe ich mich auf die folgenden Diskussionen für ihre jeweilige Definition.

  1. Mapper - in der Nähe der hier erläuterten Informationen: http://www.codeproject.com/KB/library/AutoMapper.aspx . Dies ist nicht genau das gleiche wie oben - aber am nächsten fand ich über Mapper.

  2. Builder - wie hier definiert: http://www.oodesign.com/builder-pattern.html

  3. Factory - wird hier definiert: http://www.oodesign.com/factory-pattern.html

Der Mapper ist im Wesentlichen ein Konstruktor von innen nach außen. Angenommen, Sie haben für eine Weile keinen Mapper. Wenn Sie ohnehin viele Parameter benötigen, sind dies alles Argumente für den Konstruktor. Während sich die Dinge weiterentwickeln, sind einigen Anwendungen keine zusätzlichen Attribute bekannt, die unter den Konstruktor gestellt werden müssen, wo man sie entweder berechnet oder Standard verwendet. Entscheidend ist, dass Mapper dies für Sie tun kann - und es wäre nützlicher, wenn dies mit externen Objekten verknüpft wäre, um einen solchen Algorithmus für die Konstruktion zu bestimmen.

Der Builder unterscheidet sich stark vom Mapper. Ein Builder ist wichtig, wenn ein vollständiges Objekt aus vielen Teilen des Objekts besteht. Es ist eine Art Zusammenbau der Objekte durch Zusammenfügen vieler Teile. Auch die Initialisierung der einzelnen Teilobjekte hängt mit der Existenz anderer Teile zusammen.

Die Fabrikmuster sehen von Anfang an sehr einfach aus. Es gibt ein neu erstelltes Objekt zurück. Kann mir ein gewöhnlicher Konstruktor mit einem Operator wie new () eine voll funktionsfähige Instanz geben? Warum brauche ich eine Fabrik, die mir die gleichen Ergebnisse liefert?

Die Verwendung des Factory-Musters ist jedoch in der Regel sehr spezifisch. obwohl meistens nicht in der Literatur angezeigt, wo dies angewendet wird. Normalerweise erstellt eine Anwendung eine Factory, die für verschiedene Objekte freigegeben ist, die solche Produktobjekte während der Ausführung erstellen müssen. Wenn viele solcher Produkte erstellt werden, ermöglicht die Factory-Methode das Erstellen von Objekten basierend auf bestimmten Richtlinien . Beispielsweise kann eine bestimmte Vorlage erzwungen werden, die von der Factory-Methode verwendet wird wenn alle Objekte erstellt sind. Dies ist auch keine Builder-Methode. Hier ist das Produkt nur eines (und unabhängig). Dies ist auch nicht wie Mapper; Hier ist der externe Datensatz zum Erstellen eines Objekts gemäß dem Client tatsächlich minimal. Das Fabrikmuster liefert wirklich (wie der Name schon sagt) ein durchweg ähnliches Produktobjekt!

Dipan.

8
Dipan Mehta

Wenn ich mir die Antworten ansehe, sehe ich, dass alle Befragten semantisch falsche Antworten liefern. Ich denke, das liegt daran, dass Sie sich nur allzu sehr auf die Frage konzentrieren, die sich darauf konzentriert, wie Mapper mit Fabrik oder Bauunternehmer zusammenhängt.

In der Tat ist Mapper NICHT mit Fabrik oder Erbauer verwandt. Mapper ähnelt am ehesten dem Adapter Muster (unter Verwendung der GoF-Sprache). Das Adaptermuster bietet Funktionen zum Konvertieren einer Darstellung in eine andere. Das OP verwies auf das DataSet und den DataReader in ADO.NET - wie wäre es mit dem SqlDataAdapter? Die Antwort ist im Namen. Mapper ist ein neuer Name für etwas, über das ältere Programmierer schon lange Bescheid wissen: Adapter.

Mapper konvertiert eine Darstellung in eine andere - genau die Definition des Adaptermusters.

5
Reuben Soto

die Antwort auf Ihre Frage: Ist „Mapper“ ein gültiges Entwurfsmuster? ist ja. Das Mapper-Muster ist auch als Übersetzermuster bekannt und ein dokumentiertes Muster: http://www.iro.umontreal.ca/~keller/Layla/translator.pdf

4
armandorv

Was Sie hier tun, ist eine Art Typkonvertierung (Sie konvertieren Ihre Rohdaten in ein Geschäftsobjekt). Sie können das Factory-Muster verwenden, um genau das zu tun (d. H. Typkonvertierungen), also ist Ihre Klasse in gewisser Weise eine Factory (obwohl ich dafür ein Static Factory verwenden würde).

1
Oliver Weiler

Builder kapseln komplexe Geschäftslogik, um ein Objekt zu erstellen. Mapper hingegen sollte nur die Felder von einem zum anderen kopieren.

Zum Beispiel Zuordnung vom Datenbankmitarbeiterobjekt zum Domänenmitarbeiterobjekt, Zuordnung vom Domänenmitarbeiterobjekt zum Kundenvertrag.

Builder hingegen Hosten Sie mehrere Geschäftsentscheidungen, um build ein Objekt zu erstellen. Aus Sicht der Einzelverantwortung ist dies sinnvoll.

0
user95940