El patrón DataMapper es un concepto fundamental en el desarrollo de software, especialmente en aplicaciones que siguen el enfoque de dominio. Este patrón se encarga de traducir o convertir entre dos objetos que realizan funciones similares. Por ejemplo, podríamos tener un objeto Producto y un objeto Product, donde sus atributos se traducen entre sí para cumplir roles equivalentes en diferentes contextos.
Beneficios del DataMapper
Implementar el patrón DataMapper ofrece varias ventajas:
Protección de la base de datos: No expone directamente el diseño de las tablas al API, protegiendo así la arquitectura interna.
Desacoplamiento de la API: Facilita el cambio de bases de datos sin modificar todo el código, simplemente ajustando el traductor.
Evita campos innecesarios: Permite omitir atributos que no son relevantes en la API, solo mantienen su utilidad dentro del contexto de la persistencia.
Homogeneidad del idioma: Permite mantener un único idioma en el dominio de la aplicación, evitando mezclar idiomas en el código fuente.
¿Cómo implementamos MapStruct?
Para aplicar el patrón DataMapper, utilizamos MapStruct, una herramienta que simplifica el proceso de mapeo entre objetos. Aquí los pasos iniciales para su implementación:
Instalar la dependencia de MapStruct en tu proyecto compilado con Gradle.
Configurar el plugin de IntelliJ IDEA para autocompletar estructuras de MapStruct.
Crear clases de dominio como Product y Category.
Implementar interfaces de repositorios con métodos específicos para trabajar con los objetos de dominio.
// Ejemplo de dependencia en Gradledependencies { implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
¿Cómo crear clases de dominio?
Las clases de dominio son esenciales, ya que encapsulan la lógica del negocio. Al crear estas clases, le damos estructura al proyecto para manejar objetos que representan entidades del negocio, como productos y categorías.
Ejemplo de clase Category
publicclassCategory{privateint categoryId;privateString name;privateboolean active;// Getters and Setters}
Ejemplo de clase Product
publicclassProduct{privateint productId;privateString name;privateint stock;privatedouble price;privateboolean active;privateCategory category;// Getters and Setters}
¿Cómo definir interfaces de repositorios?
Definimos interfaces con métodos que cualquier repositorio debe implementar al trabajar con productos. Esto facilita la gestión y el acceso a datos de productos dentro de una base de datos sin acoplarse a una tecnología específica.
Este enfoque garantiza que se mantenga un lenguaje común del dominio y que el acceso a los datos sea flexible, escalable y adaptable a futuros cambios en las tecnologías de almacenamiento. Con este conocimiento, estás listo para incorporar patrones de diseño avanzados en tus proyectos y mejorar la calidad de tu software aplicado a un entorno de dominio. ¡Sigue aprendiendo y mejorando tus habilidades!
Otra forma de instalar plugins en IntelliJ es ir a files > Settings o Ctrl + Alt + S / en Mac es con command + , (coma)
En el panel izquierdo se selecciona "plugins"
y solo queda buscar "MapStruct Support" e instalarlo :)
Estoy llevando mi proyecto con Maven, gracias!
Muchas gracias
Muy buenas notas
Si alguno esta viendo esto en 2022
Los pasos de instalación de MapStruct Plugin son:
Abrir opción "Preferencias"
Clic en la opción "Plugins"
Clic en el engranaje
Clic en "Instalar desde disco"
Buscan el ZIp
Clic en OK
Reiniciar el IntelliJ IDEA
Y listo :) espero les sirva
DATA MAPPER
Convertir o traducir dos objetos que pueden hacer una misma labor
No exponer directamente la base datos medianta la API
Esto garantiza que ningun agente externo, vizualice la forma del diseño de la base de datos
Desacoplar la API de una base de datos puntual
En el caso que se desee integrar una nueva base de datos con otros campos, pero que sea para el mismo proyecto, no es necesario cambiar todo el código, simplemente se crea otro traductor que sirva para traducir la nueva tabla al dominio
Evita tener campos innecesarios en la API
Evitar mezclar idiomas en el dominio
"Estamos acoplando nuestra aplicación a la capa de la persistencia y nuestro proyecto está construido bajo un enfoque de dominio" Palabras del profe
¿Alguien me apoya explicando un poco mas lo que significa?
Porfa
Cuando se construye un software siempre buscamos que exista un bajo acoplamiento entre componentes.
En este caso, MapStruct me permite evitar que los entities se conviertan en objetos transversales de la aplicación (que van desde la base de datos hasta el controlador Rest). Así tendré objetos de dominio que serán los que finalmente estarán expuestos en la API y por otra parte tengo los entities que solo vivirán en la capa de datos.
Gracias por la respuesta, ahora me queda mas claro.
Profe me puedes dar una explicacion breve del Optional que no lo tengo muy claro aún?
Cordial saludo profe, Avanzamos en el curso pero todavia no ejecutamos el proyecto teniendo en cuenta que envarias partes del codigo no es raro que nos de error a nosotros que estamos aprendiendo pensaria que seria bueno tambien probar el codigo.
¿Que ofrece el patrón Data Mapper?
No expone la DB a la API
Desacopla la API de la DB
Facilita mudar a otro moto de DB
Evita tener campos innecesarios en la API
hay algunas cosas a tener en cuenta, no es muy deseable tener variables con el mismo nombre de la clase, adicionalmente es redundante tener en las variables composiciones con el nombre de la clase por ejemplo
public class Category {
private int categoryId;// deberia de llamarse id, ya se sobre entiende que este //campo hace referencia al id de la categoriaprivateString category;//deberia llamarse name o descriptionprivate boolean active;
Buen apunte, gracias!
Muy buenas, en caso de manejar el dominio y los entities en inglés, tendriamos dos clases con el mismo nombre que puede ser un poco molesto. Que recomiendan hacer en ese caso? Tal vez le podemos poner en un sufijo Entity.
Usar ese sufijo es una muy buena práctica sí tu entidad y la clase de dominio comparten el mismo nombre.
Estoy usando Spring Tool Suite y también esta el plugin en el market, lo pueden buscar como Mapstruct Support 😁👍
Ahora entiendo todo, yo la verdad no le veía sentido al mapper, pero con esta explicación ya me hace sentido.
Si utilizamos los nombres en inglés, entonces no es necesario implementar lo del mapper?
Sí vas orientar tu aplicación en términos de dominio, si es necesario.
Sí tienen además los mismos nombres de atributos solo basta con crear el Mapper pero sin definirle ningún mapeo explicito porque se harán automáticamente.
La idea es que el objeto de dominio solo lleve lo que sea estrictamente necesario, por lo cual debería tener menos campos que el entity y en ese sentido el Mapper tendrá uno que otro ignore.
Tenia la misma duda, gracias.
DataMappers - Mapeando los datos
Nos permite desacoplar la persistencia de la aplicación. Consiste en convertir o traducir varios objetos que pueden cumplir la misma labor. De esta forma podemos:
Independizar la base de datos de la API, desacoplanto la capa de persistencia o de negocio.
Desacoplarnos de una base de datos puntua, así no tendríamos que refactorizar todo el código si la capa de persistencia cambia.
Evitar campos innecesarios en la API.
Evitar mezclar idiomas en la aplicación.
Este curso está genial! Y si te apoyas en chatGPT para profundizar más y aclarar dudas, el aprendizaje se vuelve más significativo todavía.
File
Settings
Plugins
Muchísimo más fácil
Esto de casualidad no es parecido a crear clases DTO?
Me gustó cómo explicó el concepto de Data Mapper.
Se crean los DTO y no se usan los entity en la capa de dominio debido a la implementación del patron Data Mapper.
Beneficios del Data Mapper:
Al separarse los objetos del dominio de los de la persistencia, si se cambia la bd o la table, solo hay que
hacer cambios en el lado de la persistencia, dejando el dominio intacto y no modificando la lógica de negocio.
Es más seguro porque podemos mantener en los entities los nombres de cada columna de la base de datos,
evitando usar la annotation @Column(name = “”). Podemos usar en las clases Entity propiedades en español
(si es que los nombres de los campos de la bd están en español) ya que en la parte de la lógica que es lo que va
a ver principalmente un desarrollador va a estar en inglés.