Parte de una serie sobre |
Desarrollo de software |
---|
El diseño impulsado por el dominio ( DDD ) es un enfoque importante de diseño de software , [1] que se centra en modelar el software para que se adapte a un dominio según los aportes de los expertos de ese dominio. [2] El DDD se opone a la idea de tener un único modelo unificado; en cambio, divide un sistema grande en contextos delimitados, cada uno de los cuales tiene su propio modelo. [3] [4]
En el diseño orientado al dominio, la estructura y el lenguaje del código de software (nombres de clase, métodos de clase , variables de clase ) deben coincidir con el dominio empresarial. Por ejemplo: si el software procesa solicitudes de préstamos, podría tener clases como "solicitud de préstamo", "clientes" y métodos como "aceptar oferta" y "retirar".
El diseño impulsado por el dominio se basa en los siguientes objetivos:
Los críticos del diseño basado en dominios argumentan que los desarrolladores normalmente deben implementar un alto grado de aislamiento y encapsulamiento para mantener el modelo como una construcción pura y útil. Si bien el diseño basado en dominios ofrece ventajas como la facilidad de mantenimiento, Microsoft lo recomienda solo para dominios complejos en los que el modelo ofrece ventajas claras a la hora de formular una comprensión común del dominio. [5]
El término fue acuñado por Eric Evans en su libro del mismo nombre publicado en 2003. [6]
El diseño impulsado por el dominio articula una serie de conceptos y prácticas de alto nivel. [6]
De importancia primordial es el dominio del software, el área temática a la que el usuario aplica un programa. Los desarrolladores de software construyen un modelo de dominio : un sistema de abstracciones que describe aspectos seleccionados de un dominio y puede utilizarse para resolver problemas relacionados con ese dominio.
Estos aspectos del diseño orientado al dominio tienen como objetivo fomentar un lenguaje común compartido por expertos en el dominio, usuarios y desarrolladores: el lenguaje ubicuo . El lenguaje ubicuo se utiliza en el modelo de dominio y para describir los requisitos del sistema.
El lenguaje ubicuo es uno de los pilares del DDD junto con el diseño estratégico y el diseño táctico .
En el diseño impulsado por el dominio, la capa de dominio es una de las capas comunes en una arquitectura multicapa orientada a objetos .
This article needs additional citations for verification. (July 2023) |
El diseño orientado al dominio reconoce múltiples tipos de modelos. Por ejemplo, una entidad es un objeto definido no por sus atributos, sino por su identidad . Por ejemplo, la mayoría de las aerolíneas asignan un número único a los asientos de cada vuelo: esta es la identidad del asiento. Por el contrario, un objeto de valor es un objeto inmutable que contiene atributos pero no tiene identidad conceptual. Cuando las personas intercambian tarjetas de presentación, por ejemplo, solo se preocupan por la información de la tarjeta (sus atributos) en lugar de tratar de distinguir entre cada tarjeta única.
Los modelos también pueden definir eventos (algo que sucedió en el pasado). Un evento de dominio es un evento que interesa a los expertos del dominio. Los modelos pueden estar unidos por una entidad raíz para convertirse en un agregado . Los objetos fuera del agregado pueden contener referencias a la raíz, pero no a ningún otro objeto del agregado. La raíz del agregado verifica la consistencia de los cambios en el agregado. Los conductores no tienen que controlar individualmente cada rueda de un automóvil, por ejemplo: simplemente conducen el automóvil. En este contexto, un automóvil es un agregado de varios otros objetos (el motor, los frenos, los faros, etc.).
En el diseño impulsado por el dominio, la creación de un objeto a menudo está separada del objeto en sí.
Un repositorio , por ejemplo, es un objeto con métodos para recuperar objetos de dominio de un almacén de datos (por ejemplo, una base de datos). De manera similar, una fábrica es un objeto con métodos para crear directamente objetos de dominio.
Cuando parte de la funcionalidad de un programa no pertenece conceptualmente a ningún objeto, normalmente se expresa como un servicio .
Un contexto delimitado es análogo a un microservicio . [7]
Aunque el diseño orientado al dominio no está inherentemente ligado a los enfoques orientados a objetos , en la práctica, explota las ventajas de dichas técnicas, entre ellas, las entidades o raíces agregadas como receptores de comandos o invocaciones de métodos, la encapsulación del estado dentro de las raíces agregadas más importantes y, en un nivel arquitectónico superior, los contextos delimitados.
Como resultado, el diseño impulsado por el dominio a menudo se asocia con objetos Java simples y objetos CLR simples , que son detalles de implementación técnicamente técnicos, específicos de Java y .NET Framework respectivamente. Estos términos reflejan una visión creciente de que los objetos de dominio deben definirse puramente por el comportamiento empresarial del dominio, en lugar de por un marco tecnológico más específico.
De manera similar, el patrón de objetos desnudos sostiene que la interfaz de usuario puede ser simplemente un reflejo de un modelo de dominio suficientemente bueno. Exigir que la interfaz de usuario sea un reflejo directo del modelo de dominio obligará al diseño de un modelo de dominio mejor. [8]
El diseño impulsado por el dominio ha influido en otros enfoques del desarrollo de software.
El modelado específico de dominio , por ejemplo, es un diseño impulsado por el dominio aplicado con lenguajes específicos de dominio . El diseño impulsado por el dominio no requiere específicamente el uso de un lenguaje específico de dominio, aunque podría usarse para ayudar a definir un lenguaje específico de dominio y respaldar el multimodelado específico de dominio .
A su vez, la programación orientada a aspectos facilita la eliminación de preocupaciones técnicas (como seguridad, gestión de transacciones, registro) de un modelo de dominio, lo que les permite centrarse exclusivamente en la lógica empresarial.
Si bien el diseño basado en dominios es compatible con la ingeniería basada en modelos y la arquitectura basada en modelos , [9] la intención detrás de ambos conceptos es diferente. La arquitectura basada en modelos se preocupa más por traducir un modelo en código para diferentes plataformas tecnológicas que por definir mejores modelos de dominio.
Sin embargo, las técnicas que proporciona la ingeniería basada en modelos (para modelar dominios, para crear lenguajes específicos de dominio para facilitar la comunicación entre expertos en el dominio y desarrolladores, etc.) facilitan el diseño basado en dominios en la práctica y ayudan a los profesionales a sacar más provecho de sus modelos. Gracias a las técnicas de transformación de modelos y generación de código de la ingeniería basada en modelos, el modelo de dominio se puede utilizar para generar el sistema de software real que lo gestionará. [10]
La segregación de responsabilidades entre consultas y comandos (CQRS) es un patrón arquitectónico para separar la lectura de datos (una "consulta") de la escritura de datos (un "comando"). CQRS deriva de Command and Query Separation (CQS), acuñado por Bertrand Meyer .
Los comandos modifican el estado y son aproximadamente equivalentes a la invocación de un método en raíces o entidades agregadas. Las consultas leen el estado, pero no lo modifican.
Si bien CQRS no requiere un diseño basado en dominios, hace explícita la distinción entre comandos y consultas con el concepto de raíz agregada. La idea es que una raíz agregada dada tiene un método que corresponde a un comando y un controlador de comandos invoca el método en la raíz agregada.
La raíz agregada es responsable de ejecutar la lógica de la operación y de generar una respuesta de error o simplemente de modificar su propio estado para que pueda escribirse en un almacén de datos. El controlador de comandos incorpora cuestiones de infraestructura relacionadas con el almacenamiento del estado de la raíz agregada y la creación de los contextos necesarios (por ejemplo, transacciones).
El abastecimiento de eventos es un patrón arquitectónico en el que las entidades rastrean su estado interno no por medio de serialización directa o mapeo relacional de objetos, sino leyendo y confirmando eventos en un almacén de eventos .
Cuando se combina el abastecimiento de eventos con CQRS y el diseño impulsado por dominios, las raíces agregadas son responsables de validar y aplicar comandos (a menudo haciendo que sus métodos de instancia se invoquen desde un controlador de comandos) y luego publicar eventos. Esta es también la base sobre la que las raíces agregadas basan su lógica para tratar con las invocaciones de métodos. Por lo tanto, la entrada es un comando y la salida es uno o varios eventos que se guardan en un almacén de eventos y luego, a menudo, se publican en un agente de mensajes para aquellos interesados (como la vista de una aplicación ).
El modelado de raíces agregadas para generar eventos puede aislar el estado interno aún más que cuando se proyectan datos leídos desde entidades, como en las arquitecturas estándar de paso de datos de n niveles. Un beneficio significativo es que los demostradores de teoremas axiomáticos (por ejemplo, Microsoft Contracts y CHESS [11] ) son más fáciles de aplicar, ya que la raíz agregada oculta de manera integral su estado interno. Los eventos a menudo se conservan según la versión de la instancia de la raíz agregada, lo que produce un modelo de dominio que se sincroniza en sistemas distribuidos a través de concurrencia optimista .
Aunque el diseño impulsado por dominio no depende de ninguna herramienta o marco en particular, algunos ejemplos notables incluyen: