• Saltar a la navegación principal
  • Saltar al contenido principal
Icono Jeronimo Palacios

Jeronimo Palacios & Associates

Transformación digital

  • Agile Academy
    • Scrum Mastery
  • Próximos cursos
  • Scrum.org
    • Applying Professional Scrum
    • Applying Professional Scrum for Software Development
    • Professional Scrum Master
    • Professional Scrum Master II
    • Professional Scrum Product Owner
    • Professional Scrum Product Owner Advanced
    • Scaled Professional Scrum
    • Professional Agile Leadership
    • Professional Scrum with Kanban
  • Kanban University
    • Team Kanban Practitioner
    • Kanban System Design
    • Kanban Systems Improvement
  • Servicios
    • Formación
      • Management 3.0
      • SAFe 5.0
      • Lean Change Management
      • DevOps Institute
    • Agile Coaching
      • Discover and deliver Agility
      • Solicitud de propuesta de servicios profesionales
    • Software
      • Diagnóstico de Arquitectura de Software
    • Recursos
  • Blog
  • Guías
    • Método Kanban
    • Nexus
    • Definitiva Scrum
    • Oficial Scrum
  • Acerca de
    • Videos sobre Scrum y Kanban
  • Contacto
  • Show Search
Hide Search

domain driven design

Domain Driven Design: del Modelo al Diseño

Introducción

Este es el segundo artículo sobre las lecciones aprendidas aplicando Domain Driven Design en el equipo de desarrollo de Jerónimo Palacios & Associates. 

En la anterior entrada, te hablé sobre el mapeado del dominio en el modelo. En esta ocasión, te contaré cómo realizamos el segundo paso, la implementación del modelo en el diseño. 

Creando el diseño: ida y vuelta.  

Los técnicos estamos acostumbrados a transformar modelos en diseños. Formalicemos o no el modelo en un documento, cuando nos describen un problema, inmediatamente nos ponemos a pensar solución en código. Es nuestra forma de razonar. No podemos evitarlo. 

Una de los aprendizajes más difíciles e importantes para un técnico es oponerse a este instinto. Cuando estamos construyendo el modelo debemos evitar contaminarlo con detalles de diseño para que sea útil como herramienta de comunicación con negocio. Pero esto no significa que el modelo esté aislado del diseño. No es una entidad abstracta que esté por encima y domine al diseño. Todo lo contrario, el modelo debe ser realista e implementable. 

Es totalmente normal y esperable que, como consecuencia de su trabajo,  el equipo de desarrollo encuentre problemas en el modelo. Estos problemas pueden tener su origen en la implementación o errores en el modelado del dominio puestos de manifiesto en la práctica. Sea cual sea el caso, los cambios en el modelo se evalúan con negocio (Product Owner, Business Analyst) para garantizar su consistencia.

Este proceso de realimentación mejora el modelo y, sobre todo, proporciona transparencia a negocio sobre su implementación. El conocimiento de la realidad del código por parte de negocio les permite comprender las limitaciones de la solución. Este conocimiento “técnico” es tan importante para la evolución de la aplicación como el conocimiento del equipo de desarrollo sobre el dominio del negocio. Y, de nuevo, el modelo va a jugar un papel central en este intercambio de información.  

Formalización del Diseño

El diseño es propiedad del equipo de desarrollo y ellos deciden la mejor forma de reflejarlo. En  muchas ocasiones no es necesario un documento formal. La documentación de diseño es muy costosa de mantener. Tan pronto como pongo el punto y final en un documento de diseño, queda desactualizado. Las dudas sobre la veracidad de esta documentación nos lleva continuamente a acudir a los artefactos de implementación como origen inequívoco de la verdad del sistema. En muchas ocasiones, el esfuerzo no compensa y es mejor prescindir de documentación e ir directamente a la fuente. Somos técnicos, sabemos leer el código. 

Como te comentaba en la serie de entradas sobre diagnóstico de arquitectura , la documentación formalizada de diseño es útil para proporcionar una visión rápida y general sobre la solución. En caso de necesitarla, la documentación debe limitarse a los elementos más estables. Es decir,  los más difíciles de modificar.  

El  nivel de arquitectura (servicios, orquestación, despliegue y componentes) es muy costoso de refactorizar, por lo que suele ser bastante estable. Otro caso son las clases o funciones centrales en la red de dependencias. Son aquellas que reciben más dependencias entrantes y, por lo tanto, son más significativas para la aplicación. Son difíciles de modificar porque tienen un enorme impacto colateral. Ambas vistas del sistema son muy relevantes para su mantenimiento por lo que suelen estar en la documentación formalizada de diseño. 

Patrones DDD como piezas de diseño. 

DDD propone una serie de patrones bien conocidos para mapear el modelo en el diseño. Por ejemplo: Value Objects, Entities, Factories, etc. En general, las indicaciones sobre su aplicación son muy razonables y se corresponden con el uso conocido de estos patrones. Sin embargo, el catálogo de patrones me resulta un poco reducido y de alto nivel de abstracción. Para algunos casos de uso, hemos recurrido a patrones más especializados como: builder, command, interactors o presenter. 

En general, respecto a arquitectura y patrones, somos más de Robert C Martin que de Eric Evans. Particularmente, el modelo de capas en forma de cebolla que propone Uncle Bob, me resulta más natural. Con el dominio en el centro y diana de las dependencias del sistema, frente al apilado de capas sugerido en DDD.  En cualquier caso, hay una correspondencia clara entre los niveles de abstracción de uno y otro, por lo que no son incompatibles. En la siguiente figura tienes los niveles identificados en Clean Architecture (rojo) y las correspondencias en DDD (azul)

Relación entre capas descritas por Eric Evans en DDD y Robert C Martin en Clean Architecture

Tecnologías de Desarrollo

Como describo en el artículo sobre arquitecturas emergentes, debemos centrarnos en lo realmente importante, el dominio, y aplazar  al Last Responsible Moment la elección de herramientas concretas como frameworks y middleware.

Me gusta emplear una estrategia oportunista, recurriendo a las herramientas que mejor se adaptan al caso de uso. Pero, como todos, en JPA tenemos preferencias por las tecnologías que dominamos y con las que nos sentimos más cómodos. Algunos ejemplos son el paradigma orientado a objetos y los lenguajes con validación estática de tipos. 

Paradigma OO

La programación Orientada a Objetos es una forma natural y directa de implementar la mayoría de los modelos. De los atributos de la programación orientada a objetos: abstracción, polimorfismo, herencia y encapsulamiento; es ésta última la que más me gusta y la que, por tanto, echo más en falta cuando trabajo con otros tecnologías que no le dan soporte directo (como Javascript o Python). Ocultar elementos de la implementación nos hace posible exponer una interfaz clara para dependencias y es la mejor forma de limitar el impacto de los refactoring. 

Paradigma Funcional

El  funcional se aplica muy bien en las partes del modelo que tienen una naturaleza claramente matemática. Para eso se creó. En nuestra herramienta Metrics, toda la base de cálculo se ha implementado empleando patrones funcionales:  funciones de alto nivel, inmutabilidad y librerías de colecciones. 

Validación estática de tipos. 

Los lenguajes con validación estática de tipos me resultan más cómodos para desarrollar lógica compleja. Anticipar la detección de errores al tiempo de compilación me da mayor seguridad sobre la robustez del resultado. La estrategia Shift-Left DevOps dirige nuestras prácticas. Qué puede anticipar más los chequeos, a que sea el propio IDE quien me corrige errores mientras tecleo.  

Por otro lado, tengo menos memoria que Dory. Ir tecleando y que el IDE me sugiera los métodos de una clase o me autocomplete, me da la vida. 

Por último, los patrones de refactoring están mejor soportados en este tipo de lenguajes. Si habéis sufrido el refactoring en Javascript, os sugiero probar a disfrutar de la misma experiencia con Java. 

Conclusiones

Con este artículo completo mi primera entrada sobre la aplicación de Domain Driven Design en el equipo de desarrollo de JPA. Os he contado algunas prácticas y herramientas que empleamos en JPA para realizar la transformación del modelo al diseño y su implementación. 

No cierro el tema, todo lo contrario. Me encanta debatir sobre tecnología. Pon tus comentarios o escríbeme y encontremos juntos mejores soluciones. 

Domain Driven Design o Dominio, Dominio y Dominio

Introducción

Domain Driven Design (DDD) es una práctica de desarrollo de software que pone el acento en el Dominio del Negocio como faro del proyecto y en su Modelo como herramienta de comunicación entre negocio y tecnología. En el equipo de desarrollo de JPA empleamos Domain Driven Design  como referencia para afrontar proyectos de desarrollo de cierta complejidad. Fruto de nuestros errores pero, sobre todo, de responder a las preguntas honestas de unos compañeros y los dardos envenenados de otros, hemos ido refinando su aplicación. En este artículo te presento algunas conclusiones y prácticas que pueden facilitarte la aproximación a sus principios. 

Lo más importante es el Dominio. 

Parece de perogrullo ¿Verdad? Como técnico, lo que primero llamó mi atención de DDD fue el conjunto de patrones de diseño recomendados para implementar el modelo: Value Object, Entity, Service, Factory, Repository, etc. Los patrones son herramientas con larga tradición y consolidados en la industria (GOF , Martin Fowler, Eric Freeman, etc). Esta experiencia previa  me llevó a pensar que eran, precisamente estos patrones, la mayor contribución de DDD. Y me equivocaba. 

Lo realmente relevante del DDD es la machacona insistencia en el Dominio como fuente de verdad para el desarrollo de software. Hay que volver a él siempre que pienses que te estás desviando del camino correcto. Por ejemplo, cuando no estés seguro del valor de la funcionalidad que estás desarrollando o cuando sospeches que estás matando moscas a cañonazos (overengineering). Hay que aprender a tener el dominio siempre visible y poner en duda el valor de todo lo que no quepa en él.

“Poner en duda todo desarrollo que no esté contemplado por el dominio es la principal lección de Domain Driven Design”

¿Cómo concretamos el Dominio?

Mediante su modelo.  El modelo es un conjunto de artefactos (diagramas, documentos, prototipos, etc. ) que contiene una representación significativa del Dominio. Es un paso intermedio entre el dominio del negocio y el diseño tecnológico. El valor del modelo es doble: 

  1. Es el glosario del  Lenguaje Ubicuo (“Ubiquitous Language”) . Debe ser comprensible y significativo para negocio y tecnología. Todos los miembros del equipo (incluido negocio) emplean los términos del modelo en sus comunicaciones: Historias de Usuario, Casos de Uso, Features, Tareas, etc. 
  2. Son los cimientos y el espejo del diseño de software.  El equipo de desarrollo emplea el modelo para crear un diseño que lo implementa. Pero además, mantendrá sincronizado diseño y modelo a lo largo de toda la vida del proyecto. Todo cambio en el diseño deba ser validado contra el modelo. Si como consecuencia del desarrollo se considera que el modelo debe ser ajustado, los cambios se revisan con negocio y se llevan al lenguaje ubicuo. 

El punto 2 es el que requiere un mayor esfuerzo de adaptación y concentración cuando nos introducimos en DDD. Mantener sincronizado modelo y diseño es costoso. Es precisamente este coste, el que te lleva a valorar con mucho más cuidad los cambios en el desarrollo. El temido efecto: “pues ya que estoy…”. Pesar la contribución de valor de un cambio frente a su coste se convierte en un ejercicio continuo. 

Elaboración del Modelo

En DDD el modelo nacerá y evolucionará mediante dos fuerzas: negocio y desarrollo. Ambos puntos de vista deben estar implicados en su creación desde el comienzo. El equipo de desarrollo debe apreciar el modelo como un producto más de su trabajo, comprender cómo le ayuda a crear mejores soluciones y sentirse tan orgulloso de la calidad del modelo como de la del código. 

Delegar la creación o el mantenimiento del modelo a un analista externo al equipo, simplemente, no funciona. El equipo debe estar implicado en el esfuerzo cognitivo de análisis y modelado del dominio, sin intermediarios. Es la única forma de mantener un proceso ágil y garantizar la implicación del equipo en su mantenimiento. 

Herramientas de Modelado

Ya soy un veterano de esta industria. He pasado por procesos pesados como RUP. donde se recurre sistemáticamente a artefactos de modelado para comunicar entre etapas. Cuando trabajé  como business analyst o como diseñador, empleé extensivamente UML y BPMN. Posteriormente, con todo el movimiento Agile y especialmente XP, evité estas herramientas bajo el principio de que el código debía ser autoexplicativo. Como siempre, en el equilibrio se encuentra la virtud.

Las herramientas de modelado (UML entre otras) son muy útiles en la construcción de un marco significativo para todos los actores. El código, es mucho más difícil de entender por negocio. Incluso empleando frameworks específicamente adaptados para hacerlos más expresivos, como Domain Specific Languages. 

El código puede ser suficiente para el diseño. La organización en módulos y componentes, una estrategia consistente de asignación de responsabilidades, así como unas prácticas de nombrado uniformes, deben hacer evidente el diseño. 

Puedes apoyarte en herramientas de análisis de código que tienen muchos IDEs para crear diagramas con las entidades y dependencias presentes en el software. Esto facilita la comprensión del diseño y su validación contra el modelo. Los diagramas de análisis tienen la ventaja de ser efímeros, los creamos y los desechamos sin excesivo coste, por lo que no tenemos que gestionarlos. La ausencia de un documento de diseño evita que reemplace a la verdad reflejada por el código. 

Ten cuidado con UML. Es una herramienta muy versátil que permite introducir aspectos de implementación. El Modelo NUNCA debe contener detalles como herencia, encapsulamiento o tipos concretos. Y no lo digo porque el modelo deba ser agnóstico respecto a la tecnología de implementación (raramente buscamos eso en un proyecto), sino porque pierde su papel como paso intermedio al diseño. Recuerda,  es una abstracción empleada para comunicar con negocio y para guiar el desarrollo. 

Es un auténtico sufrimiento estar continuamente evitando escribir detalles de diseño en el modelo. Pero este es precisamente el objetivo de DDD. Forzar el uso por todos los interlocutores de un nivel de abstracción compatible con el lenguaje ubicuo. 

Gestión del Modelo

He trabajado con compañeros que prefieren crear los modelos a mano (con rotulador). El principal argumento es que reflejan la naturaleza siempre cambiante del negocio en un artefacto que está siempre “en construcción”

A míi me resulta farragoso. Si empleamos una pizarra, se borra accidentalmente. Si empleamos papel, rápidamente se llena de tachones y estamos más tiempo pasando a limpio que creando. En ambos casos, la información es difícil de compartir. 

Yo prefiero un formato digital. He empleado herramientas especializadas como Visual Paradigm, o ArgoUML. Conozco todo lo que me aportan y también todo lo que me sobra. Por eso, en muchas ocasiones, prefiero emplear una herramienta más ligera, tipo diagramas. Draw.io me funciona bien para proyectos pequeños y medianos. No obstante, siempre estoy revisando las herramientas disponibles. Si estás usando alguna que te vaya bien, por favor, ponlo en los comentarios. 

Conclusión: Vigila el Modelo

Domain Driven Design es una técnica que implica dos transformaciones, del negocio al modelo y del modelo al software

El modelo juega un papel central para asegurar la correspondencia entre el software y el negocio al que debe representar. El modelo debe estar siempre presente en la mente, en los ordenadores y en las pizarras de los equipos multidisciplinares. Buscamos una mentalidad de “Policía del Modelo” que persiga cualquier desviación de la consistencia de esta correspondencia. 

Este es el primero de una serie sobre lo que hemos aprendido aplicando DDD en Jerónimo Palacios y Asociados. En el próximo, bajaré a la transformación del modelo en diseño. Algunas soluciones propuestas por DDD que hemos empleado y otras que no. 

Imagenes :

  • Matthew Henry on Unsplash
  • Etienne Girardet on Unsplash

Para saber más:

En nuestra formación DevOps profundizamos el papel de Domain Driven Design en la creación de soluciones desacopladas, fáciles de testar y de desplegar. Si te interesa saber más, rellena este formulario para que te podamos enviar información.

Mantente al día a través de nuestra Newsletter Susbribirse

Jeronimo Palacios & Associates

Copyright © 2023 · Jerónimo Palacios & Associates S.L.

  • Aviso legal
  • Condiciones de venta
  • Política de cookies
  • Política de privacidad