Un patrón común que veo es lo que se conoce como el Mapper
patrón (que no debe confundirse con el DataMapper
que es algo completamente diferente), que toma como argumento algún tipo de fuente de datos "en bruto" (por ejemplo, un ADO.NET DataReader
o DataSet
) y asigna los campos a propiedades en un objeto de negocio / dominio. Ejemplo:
class PersonMapper
{
public Person Map(DataSet ds)
{
Person p = new Person();
p.FirstName = ds.Tables[0].Rows[0]["FirstName"].ToString();
// other properties...
return p;
}
}
La idea es su Gateway / DAO / Repository / etc. llamará al Mapper antes de que regrese, para que obtenga un objeto comercial rico en comparación con el contenedor de datos subyacente.
Sin embargo, esto parece estar relacionado, si no es idéntico, con el patrón Factory (en el lenguaje DDD, de todos modos), que construye y devuelve un objeto de dominio. Wikipedia dice esto re: la fábrica DDD:
Factory: los métodos para crear objetos de dominio deben delegar a un objeto Factory especializado de manera que las implementaciones alternativas puedan intercambiarse fácilmente.
A partir de esa cita, la única diferencia en la que puedo pensar es que la Fábrica de estilo DDD podría parametrizarse para que pudiera devolver un tipo de objeto especializado si fuera necesario (por ejemplo, BusinessCustomer versus ResidentialCustomer) mientras el "Mapper" está codificado para una clase específica y solo hace traducción.
Entonces, ¿hay alguna diferencia entre estos dos patrones o son esencialmente lo mismo con diferentes nombres?
fuente
DataMapper
patrón accedía a la base de datos, mientras que este "Mapper" no se extrae de la base de datos, solo convierte un conjunto de resultados de algún tipo en un objeto.Respuestas:
Aunque esta es la primera vez que escucho sobre el patrón Mapper, para mí suena más como el patrón Builder que como Factory.
En el patrón Factory encapsula la lógica para crear objetos de varias clases relacionadas. El primer ejemplo sería una situación en la que necesita crear un objeto de una subclase particular de alguna clase base abstracta dependiendo de algunos parámetros. Por lo tanto, una Fábrica siempre devuelve un puntero o una referencia a la clase base, pero en realidad crea un objeto de la clase derivada adecuada en función de los parámetros que le proporcione.
Por el contrario, una clase Builder siempre crea objetos de la misma clase. Lo usaría si la creación de un objeto es complicada, por ejemplo, su constructor toma muchos argumentos, y no todos pueden estar disponibles al instante. Por lo tanto, un objeto generador podría ser un lugar que almacena los valores para los argumentos del constructor hasta que los tenga todos y esté listo para crear el "producto", o puede proporcionar valores predeterminados razonables y permitirle especificar solo los argumentos cuyos valores necesita cambio. Un caso de uso típico para el patrón Builder es crear objetos que pueda necesitar en una prueba unitaria, para evitar saturar el código de prueba con toda la lógica de creación.
Para mí, un Mapper suena como una variante de un Builder, donde los parámetros del constructor vienen en forma de un registro de base de datos o alguna otra estructura de datos "en bruto".
fuente
Lo único común sobre Mapper, Builder y Factory es que entregan un "producto construido" y una instancia de objeto de un tipo. Para evitar cualquier confusión, me refiero a las siguientes discusiones para su respectiva definición.
Mapper: cerca de lo que se explica aquí: http://www.codeproject.com/KB/library/AutoMapper.aspx . Esto no es exactamente lo mismo que el anterior, pero lo más cercano que encontré sobre mapper.
Constructor - como se define aquí: http://www.oodesign.com/builder-pattern.html
Fábrica: se define aquí: http://www.oodesign.com/factory-pattern.html
El mapeador es esencialmente un constructor de adentro hacia afuera. Suponga por un tiempo, si no tiene un mapeador: cuando de todos modos necesita muchos conjuntos de parámetros, todos son argumentos sobre el constructor. Ahora, a medida que las cosas evolucionan, algunas aplicaciones no son conscientes de los atributos adicionales que deben ir debajo del constructor donde uno lo calcula o usa el valor predeterminado. Lo crítico es que el mapeador puede hacer esto por usted, y sería más útil si esto tiene un vínculo con objetos externos para decidir dicho algoritmo para la construcción.
El generador es muy diferente del mapeador. Un constructor es esencial cuando un objeto completo se compone usando muchas partes del objeto. Es como ensamblar los objetos al unir muchas partes. Incluso la inicialización de los objetos de parte individual está relacionada con la existencia de otras partes.
Los patrones de fábrica parecen muy simples desde el principio. Devuelve objetos recién construidos. ¿Si algún constructor ordinario me puede dar una instancia completamente funcional usando un operador como new ()? ¿Por qué necesitaría una fábrica que me dé los mismos resultados?
Sin embargo, el uso del patrón de fábrica suele ser muy específico; aunque con mayor frecuencia, no se muestra en la literatura donde se aplica esto. Por lo general, una aplicación crea una fábrica que se comparte con varios objetos que necesitan crear dichos objetos de producto durante la ejecución. Cuando se crean muchos de estos productos, el método Factory permite la creación de objetos basados en cierta política, por ejemplo, se puede forzar una plantilla determinada que se utiliza con el método factory cuando se crean todos los objetos. Esto no es como un método de construcción; Aquí el producto es solo uno (e independiente). Esto tampoco es como el mapeador; aquí el conjunto de datos externos para crear objetos según el cliente es realmente mínimo. ¡El patrón de fábrica realmente proporciona (como su nombre lo indica) un objeto de producto consistentemente similar!
Dipan
fuente
La respuesta a su pregunta: ¿Es “Mapper” un patrón de diseño válido? Es sí. El patrón Mapper, también se conoce como Translator Pattern y es un patrón documentado: http://www.iro.umontreal.ca/~keller/Layla/translator.pdf
fuente
Cuando miro las respuestas, veo que todos los encuestados proporcionan respuestas semánticamente incorrectas. Creo que esto se debe a que está demasiado concentrado en la pregunta, que se centra en cómo se relaciona el mapeador con la fábrica o el constructor.
Cuando, de hecho, Mapper NO es similar a la fábrica o al constructor. Mapper se parece mucho al patrón adaptador (usando el lenguaje GoF). El patrón del adaptador proporciona funcionalidad para convertir una representación en otra. El OP se refirió al DataSet y al DataReader en ADO.NET, ¿qué tal el SqlDataAdapter? La respuesta está en el nombre. Mapper es un nuevo nombre para algo que los programadores más antiguos conocen desde hace mucho tiempo: los adaptadores.
Mapper convierte una representación en otra, la definición misma del patrón del adaptador.
fuente
Lo que está haciendo aquí es en realidad algún tipo de conversión de tipo (convierte sus datos sin procesar en un objeto comercial). Puede usar el patrón de fábrica para hacer exactamente eso (es decir, conversiones de tipo), así que sí, de alguna manera, su clase es una fábrica (aunque usaría una fábrica estática para eso).
fuente
Los constructores encapsulan la lógica empresarial compleja para construir un objeto. Mapper, por otro lado, solo debe copiar los campos de uno a otro.
Por ejemplo, mapear del Objeto del Empleado de la Base de Datos al Objeto del Empleado del Dominio, mapear del Objeto del Empleado del Dominio al Contrato del Cliente.
Los constructores, por otro lado, alojan múltiples decisiones comerciales para construir un objeto. Desde el punto de vista de la responsabilidad única, esto tiene sentido.
fuente