Un modèle courant que je vois est ce qu’on appelle le Mapper
modèle (à ne pas confondre avec DataMapper
ce qui est autre chose), qui prend comme argument une sorte de source de données "brute" (par exemple un ADO.NET DataReader
ou DataSet
) et mappe les champs sur propriétés sur un objet métier / domaine. Exemple:
class PersonMapper
{
public Person Map(DataSet ds)
{
Person p = new Person();
p.FirstName = ds.Tables[0].Rows[0]["FirstName"].ToString();
// other properties...
return p;
}
}
L'idée étant votre passerelle / DAO / référentiel / etc. appelle dans le mappeur avant son retour, vous obtenez donc un objet métier riche par rapport au conteneur de données sous-jacent.
Cependant, cela semble être lié, sinon identique, au modèle Factory (de toute façon dans le langage DDD), qui construit et retourne un objet de domaine. Wikipedia dit ceci: l'usine DDD:
Factory: les méthodes de création d'objets de domaine doivent être déléguées à un objet Factory spécialisé, de sorte que les implémentations alternatives puissent être facilement échangées.
À partir de cette citation, la seule différence à laquelle je pouvais penser est que l’usine de style DDD puisse être paramétrée de manière à renvoyer un type d’objet spécialisé si le besoin s’en faisait sentir (par exemple, BusinessCustomer contre ResidentialCustomer) alors que le "Mappeur" était associé à une classe spécifique. et seulement la traduction.
Y a-t-il une différence entre ces deux modèles ou s'agit-il essentiellement de la même chose avec des noms différents?
la source
DataMapper
modèle d'accès à la base de données lui-même était accessible, alors que ce "mappeur" ne extrait pas de la base de données, mais convertit simplement un ensemble de résultats en un objet.Réponses:
Même si c’est la première fois que j’entends parler du motif Mapper, cela ressemble plus au motif Builder qu’à la Factory.
Dans le modèle Factory, vous encapsulez la logique permettant de créer des objets d'un certain nombre de classes liées. Le premier exemple serait une situation dans laquelle vous devez créer un objet d'une sous-classe particulière d'une classe de base abstraite en fonction de certains paramètres. Ainsi, une fabrique renvoie toujours un pointeur ou une référence à la classe de base, mais crée en fait un objet de la classe dérivée appropriée en fonction des paramètres que vous lui spécifiez.
En revanche, une classe Builder crée toujours des objets de la même classe. Vous l'utiliserez si la création d'un objet est compliquée. Par exemple, son constructeur prend beaucoup d'arguments, qui ne sont pas tous disponibles instantanément. Ainsi, un objet générateur peut être un emplacement qui stocke les valeurs des arguments du constructeur jusqu'à ce que vous les ayez tous et prêt à créer le "produit", ou il peut fournir des valeurs par défaut raisonnables et vous permettre de spécifier uniquement les arguments dont vous avez besoin changement. Un exemple typique d'utilisation du modèle de générateur est la création d'objets dont vous pourriez avoir besoin dans un test unitaire, afin d'éviter d'encombrer le code de test avec toute la logique de création.
Pour moi, un mappeur ressemble à une variante d'un constructeur, où les paramètres du constructeur se présentent sous la forme d'un enregistrement de base de données ou d'une autre structure de données "brute".
la source
La seule chose commune à propos de Mapper, Builder et Factory, c'est qu'ils fournissent un "produit construit" - et une instance d'objet d'un type. Pour éviter toute confusion, je me réfère aux discussions suivantes pour leur définition respective.
Mappeur - proche de ce qui est expliqué ici: http://www.codeproject.com/KB/library/AutoMapper.aspx . Ce n'est pas exactement la même chose que ci-dessus - mais j'ai trouvé le mappeur le plus proche.
Constructeur - tel que défini ici: http://www.oodesign.com/builder-pattern.html
Factory - est défini ici: http://www.oodesign.com/factory-pattern.html
Le mappeur est essentiellement un constructeur. Supposons un instant que vous n'ayez pas de mappeur - Lorsque vous avez de toute façon besoin de plusieurs jeux de paramètres, ils sont tous des arguments du constructeur. Au fur et à mesure que les choses évoluent, certaines applications ne sont pas conscientes des attributs supplémentaires qui doivent passer sous le constructeur, où ils sont calculés ou utilisent les valeurs par défaut. L'essentiel est que le mappeur puisse le faire pour vous - et qu'il serait plus utile s'il existe un lien avec des objets externes pour décider d'un tel algorithme pour la construction.
Le constructeur est très différent du mappeur. Un générateur est essentiel lorsqu'un objet complet est composé à l'aide de plusieurs parties de l'objet. C'est un peu comme assembler les objets en assemblant plusieurs pièces. Même l'initialisation des objets de pièce individuels est liée à l'existence d'autres pièces.
Les modèles d'usine semblent très simples au début. Il retourne des objets nouvellement construits. Si un constructeur ordinaire peut me donner une instance entièrement fonctionnelle en utilisant un opérateur comme new ()? Pourquoi aurais-je besoin d'une usine qui me donne les mêmes résultats?
Cependant, l'utilisation du modèle d'usine est généralement très spécifique; bien que le plus souvent, n'apparaisse pas dans la littérature où cela est appliqué. Généralement, une application crée une fabrique qui est partagée avec divers objets qui doivent créer de tels objets de produit lors de l'exécution. Lorsque de nombreux produits de ce type sont créés, la méthode Factory permet de créer des objets en fonction de certaines règles. Par exemple, il est possible de forcer un certain modèle utilisé par la méthode Factory lorsque tous les objets sont créés. Ce n'est ni comme une méthode de construction; ici le produit est unique (et indépendant). Ce n'est pas non plus comme mappeur; Ici, le jeu de données externe permettant de créer un objet selon le client est en réalité minimal. Le modèle d'usine fournit (comme son nom l'indique) des objets produits toujours similaires!
Dipan.
la source
la réponse à votre question: Est-ce que “Mapper” est un modèle de conception valide? est oui. Le modèle Mapper, également connu sous le nom de Modèle de traducteur, est un modèle documenté: http://www.iro.umontreal.ca/~keller/Layla/translator.pdf
la source
En parcourant les réponses, je constate que les répondants fournissent tous des réponses sémantiquement incorrectes. Je pense que c’est parce que vous êtes tous trop concentrés sur la question, qui est axée sur la relation entre le mappeur et l’usine ou le constructeur.
Quand en fait, Mapper ne ressemble pas à une usine ou à un constructeur. Le mappeur ressemble plus au modèle d' adaptateur (utilisant le langage GoF). Le modèle d'adaptateur fournit une fonctionnalité permettant de convertir une représentation en une autre. Le PO faisait référence au DataSet et au DataReader dans ADO.NET - que diriez-vous du SqlDataAdapter? La réponse est dans le nom. Mapper est un nouveau nom pour quelque chose que les programmeurs plus anciens connaissent depuis longtemps: les adaptateurs.
Mapper convertit une représentation en une autre - la définition même du modèle d'adaptateur.
la source
Ce que vous faites ici est en réalité une sorte de conversion de type (vous convertissez vos données brutes en un objet métier). Vous pouvez utiliser le modèle d'usine pour faire exactement cela (c.-à-d. Les conversions de types), alors oui, d'une manière ou d'une autre, votre classe est une usine (bien que j'utiliserais une usine statique pour cela).
la source
Les générateurs encapsulent une logique métier complexe pour créer un objet. Mapper, d'autre part, devrait simplement copier les champs de l'un à l'autre.
Par exemple, mapper d'un objet employé de base de données à un objet employé du domaine, mapper d'un objet employé du domaine à un contrat client.
Les constructeurs, quant à eux, hébergent plusieurs décisions commerciales pour créer un objet. Du point de vue de la responsabilité unique, cela a du sens.
la source