Domain Driven Design
Diseño guiado por el dominio
https://lapastillaroja.net/2014/06/ddd/
Se supone que la duplicidad de datos es mala, entonces tener el dato en un único sitio una sola vez será bueno, pues resulta ser que no. Ejm Pensamos que podría ser una buena idea desnormalizar el modelo y guardar el nombre del barrio directamente en la tabla de direcciones (a fin de cuentas los nombres de los barrios no cambian tan frecuentemente) eso ocupará más espacio a cambio de reducir el número de lecturas necesarias para cada operación.
_Ejm _Puede haber muchísimos más prospectos que clientes en una base de datos, quizá un ratio de 100 a 1. El diseño ingenuo del sistema es poner un campo “tipo de cliente” que indica en la tabla si el registro es prospecto o es cliente, aunque también podría ser ex-cliente, o incluso haber fallecido. Esto obliga a los usuarios a filtrar todas sus consultas por tipo de cliente. En un acercamiento DDD habría dos Contextos Acotados, el contexto de prospección comercial y el contexto de gestión de clientes reales con un procedimiento de conversión del prospecto en cliente. Los contextos acotados no tienen porqué modelizar sólo área funcionales, sino que pueden estar creados por razones puramente técnicas. El mejor ejemplo de ello son los datawarehouse donde se almacena la misma información que el contexto transaccional pero con una disposición de datos que es mucho mejor para elaborar informes.
Entablar conversaciones con los usuarios para definir un Lenguaje Ubícuo. En el ejemplo anterior el usuario puede decir: “quiero convertir a un prospecto en cliente cuando se cierre una venta”, es el punto de partida para definir con precisión lo que es un prospecto, lo que es un cliente y cuándo y cómo se convierte uno en el otro.
Los procesos cuyo flujo de trabajo requiera más de un contexto acotado deben implementarse como Servicios. Puede que la conversión de prospecto en cliente la haga un usuario desde una aplicación web, pero también podría ser que la conversión se efectuase automáticamente tras recibir una señal de una web externa. Por consiguiente la conversión de prospecto en cliente debe ser un servicio invocable desde cualquier parte y no sólo desde la capa del controlador de la aplicación web.
Un servicio esencial cuando se tienen contextos acotados es el de comprobación de consistencia y consolidación de datos.Si es posible mantener todos los contextos dentro de la misma base de datos a mi me gusta mantener la sincronización con disparadores (triggers) y procedimientos almacenados en el SGBDR.
https://devexperto.com/domain-driven-design-1/ https://devexperto.com/domain-driven-design-2/
Ubiquitous language
Lenguaje común
Uno de los mayores problemas que surgen durante el desarrollo de proyectos software es la comunicación entre los desarrolladores y los expertos del dominio. Cada vez que se realiza una traducción se malinterpretan y confunden conceptos, los cuales hacen que el software contenga incoherencias, y contradicciones dentro del código que provocarán errores en el sistema. Para ser capaces de generar un lenguaje común, los desarrolladores tenemos que obtener el conocimiento necesario del dominio, mientras que los expertos del dominio deben formar parte activa en el desarrollo del software. El proceso para llegar a un lenguaje común es iterativo, de tal manera que deberemos ejercitar el lenguaje y pulirlo mediante su utilización tanto en diagramas, como en escrito, y especialmente en la comunicación verbal.
Para llevar a cabo la tarea de vincular el conocimiento del dominio a la implementación del modelo disponemos de diferentes elementos.
Entities
Son objetos del modelo que se caracterizan por tener identidad en el sistema, los atributos que contienen no son su principal característica. Representan conceptos con una identidad que se mantienen en el tiempo, y que con frecuencia también se mantienen bajo distintas representaciones de la entidad.
Deben poder ser distinguidas de otros objetos aunque tengan los mismos atributos. Tienen que poder ser consideradas iguales a otros objetos aún cuando sus atributos difieren.
Debemos usar entidades únicamente para objetos que realmente lo requieran, lo cual tiene dos ventajas importantes. Por un lado, no incluiremos complejidad innecesaria en objetos que no requieran ser identificados, por otro lado al reducir el número de entidades en el sistema seremos capaces de identificarlas rápidamente.
Value Objects
Al contrario que las entidades los value objects representan conceptos que no tienen identidad. Simplemente describen características. Por lo tanto solo nos interesan sus atributos.
Los value object representan elementos del modelo que se describen por el QUÉ son, y no por QUIÉN o CUÁL son, suelen ser modelados como inmutables.
Services
Los servicios representan operaciones, acciones o actividades que no pertenecen conceptualmente a ningún objeto de dominio concreto. Los servicios no tienen ni estado propio ni un significado más allá que la acción que los definen.
Son definidos en términos de lo que pueden hacer y por tanto tienden a ser nombrados como verbos. Los verbos utilizados para nombrar a los servicios deben pertenecer al ubiquitous language, o ser introducidos en el en caso de que aún no lo sean. A la hora de implementarlos tanto sus parámetros como resultados deben ser objetos pertenecientes al dominio.
Un servicio debe de cumplir tres características principales:
- La operación que lo define está relacionada con un concepto de dominio, pero no es natural modelarlo como una entidad o un value object.
- Su interfaz se especifica usando otros elementos del modelo de dominio.
- La operación no tiene estado, por lo que cualquier cliente podría usar cualquier instancia del servicio sin tener en cuenta las operaciones que se han realizado con anterioridad en esa instancia.
Podemos dividir los servicios en tres tipos diferentes según su relación con el núcleo del dominio.
Domain services
Son responsables del comportamiento más específico del dominio, es decir, realizan acciones que no dependen de la aplicación concreta que estemos desarrollando, sino que pertenecen a la parte más interna del dominio y que podrían tener sentido en otras aplicaciones pertenecientes al mismo dominio. Por ejemplo, crear un usuario, actualizar los detalles de un cliente, etc…
Application services
Son responsables del flujo principal de la aplicación, es decir, son los casos de uso de nuestra aplicación. Son la parte visible al exterior del dominio de nuestro sistema, por lo que son el punto de entrada-salida para interactuar con la funcionalidad interna del dominio. Su función es coordinar entidades, value objects, domain services e infrastructure services para llevar a cabo una acción. Por ejemplo, realizar un pago, añadir un producto al carrito de la compra, realizar una transferencia a otra cuenta, etc…
Infrastructure services
Declaran comportamiento que no pertenece realmente al dominio de la aplicación pero que debemos ser capaces de realizar como parte de este. Por ejemplo, enviar un email de confirmación tras realizar un pago, loguear transacciones, etc…
Para aclarar la diferencia entre los diferentes servicios y sus responsabilidades pongamos el ejemplo de un application service que dados unos productos en el carrito de la compra realiza el pago. Vamos a nombrar nuestro application service como MakePaymentService.
La responsabilidad de _MakePaymentService _es la coordinación del flujo para realizar un pago. Por otro lado, para realizar la acción de validar el usuario utilizariamos un _ValidateUserService _que sería un domain service y que tendría la responsabilidad de validar que el usuario es válido, ya que a priori es una orden simple que está relacionada con un concepto de dominio. En cambio, para la acción de enviar un email de confirmación al usuario, utilizariamos _SendEmailService _que en este caso sería un infrastructure service, ya que es una acción que nuestro dominio debe ser capaz de realizar pero que no pertenece al mismo.
Layered architecture
Un sistema software está compuesto por muchas partes, de las cuales,la parte que resuelve problemas para el dominio es una porción pequeña, aunque su importancia es desproporcionada a su tamaño.
Para ser capaces de trabajar con el dominio sin perdernos en otros detalles presentes en el software necesitamos desacoplar los objetos de dominio de otras funciones del sistema. Tendremos que aislar nuestro dominio del resto del sistema para asi evitar confundir conceptos pertenecientes al dominio con conceptos que solo están relacionado con la tecnología utilizada.
Podemos utilizar cualquiera de las muchas arquitecturas que existen para aislar las distintas partes del sistema, pero la opción que elijamos debería dividir nuestro sistema en al menos cuatro capas: presentación, aplicación, dominio e infraestructura.
Presentation
Capa responsable demostrar la información al usuario e interpretar los eventos de entrada del usuario.Cabe destacar que el usuario puede ser un ser humano u otro sistema que se comunica con el nuestro.
Application
Capa que declara las funcionalidades que el software tiene que llevar a cabo y orquesta los objetos de dominio para resolver los distintos problemas.Esta capa no contiene reglas de negocio o conocimiento, solamente coordina y delega el trabajo a la colaboración de los objetos de dominio que se encuentran en la la siguiente capa.
Domain
Capa donde se encuentran los conceptos del dominio y las reglas de negocio. Es la capa más importante del sistema y es la que realmente aporta valor y resuelve los problemas para los que un determinado software es creado.
Infrastructure
Capa que provee las implementaciones que apoyan a las capas definidas anteriormente. Aquí se encapsulan la mayoría de las decisiones tecnológicas adoptadas para un sistema, por ejemplo: el envío del email de confirmación tras un pago, persistencia para el dominio, comunicación con otros sistemas, etc…
La forma DDD
Un principio detrás de DDD es cerrar la brecha entre los expertos del dominio y los desarrolladores utilizando el mismo lenguaje para crear la misma comprensión.
Un Dominio es una "esfera del conocimiento", por ejemplo el negocio que la compañía dirige. Un dominio también se llama un espacio de problema. Podemos dividir el problema grande en más pequeños. Esto puede ayudarnos a diseñar una mejor solución, esto se llama un mapa de contexto, y es el punto de partida para cualquier modelación adicional.
Un espacio de solución también se denomina contexto limitado y es el mejor alinear un espacio de problema / subdominio con un espacio de solución / contexto limitado.
Building blocks
Aqui voy
https://www.mirkosertic.de/blog/2013/04/domain-driven-design-example/