DEV Community

MartIden
MartIden

Posted on

Implementación del diseño basado en el dominio: Bloques importantes del diseño basado en modelos

Objetos de valor

Soy un gran fan de los objetos de valor. Creo que son el corazón de la POO. Aunque parecen simples, los objetos de valor de DDD son un serio punto de confusión para muchos, incluido yo. He leído y escuchado muchas maneras diferentes de describir los objetos de valor desde una variedad de perspectivas. Por suerte, cada una de las diferentes explicaciones, en lugar de entrar en conflicto entre sí, me ayudó a construir una comprensión más profunda de los objetos de valor.

Los objetos de valor son accesibles por su valor y no por su identidad. No tienen identidad, son inmutables, tienen una gran cohesión y también pueden ser objetos autovalorizantes. Sus valores no cambian (o cambian raramente) y no tienen ciclo de vida. Algunos ejemplos son las monedas, las fechas, los países, etc.

Eric Evans define el objeto valor como sigue:

Un objeto que representa un aspecto descriptivo del dominio que no tiene identidad conceptual se llama Objeto Valor. Los objetos de valor se instancian para representar elementos del diseño que nos importan sólo por lo que son, no por lo que son.

En este caso, creo que aspecto descriptivo significa que son (no siempre) el estado de una entidad, describiendo algo sobre la entidad o las cosas que posee. Los objetos de valor pueden tener un ID, pero, como dice Evans, no tienen una identidad conceptual. Esto significa que no tienen una identidad en el dominio. Por ejemplo, pueden tener IDs utilizando algunas estrategias de persistencia de la base de datos que no tienen ninguna definición en el dominio.

Hay dos claves que hacen que los objetos de valor sean importantes:

  • Representar un concepto descriptivo
  • Aumentar la explicitud

Cuando un concepto no tiene una identidad conceptual, es una gran pista de que debe ser un objeto de valor. La encapsulación es muy importante y debe evitarse a toda costa. Todos los atributos deben ser privados o estar protegidos por defecto y no se permite ningún atributo público.

Los objetos de valor son combinables. Esto significa que sus valores pueden ser combinados. Como he mencionado antes, los objetos valor son inmutables, y el resultado será un nuevo objeto valor con el valor deseado. Los objetos originales permanecen sin cambios.

Cuando quieras convertir un objeto valor en una cadena, asegúrate de que devuelves un objeto valor completo:

$Distance = new Distance(7, 'kilometers');
// The statement is incomplete
$this->assertEquals('7', (string) $Distance);

Debería serlo:

$Distance = new Distance(7, 'kilometers');
// The statement is complete now
$this->assertEquals('7 kilometers', (string) $Distance);

Como ves, el primero está incompleto porque el 7 es confuso. No está claro qué tipo de distancia se ha devuelto. ¿Son metros, centímetros, millas o pulgadas?

Entidades

Las entidades son objetos accesibles con una identidad en nuestra aplicación. Exactamente, de hecho, una entidad son conceptos de dominio con identidad y continuidad.

Cada entidad debe tener una forma operativa de establecer su identidad con otros objetos, y es distinguible incluso de otro objeto con los mismos atributos descriptivos. Debe garantizarse que un atributo de identificación sea único dentro del sistema (como el UUID); sin embargo, ese sistema está definido, incluso si está distribuido, e incluso cuando los objetos se archivan.

Una de las cosas más importantes de las entidades es garantizar que se autovaliden y sean siempre válidas. Esto también es cierto para las invariantes. Las invariantes son hechos sobre una entidad. Limitan los valores de ciertos atributos y deben estar dentro de un cierto rango para ser una representación precisa de la entidad que se está modelando y asegurarse de que todos ellos se implementan; de lo contrario, existiría el peligro del objeto anémico.

Usar setters en tus entidades es un gran riesgo. Esto llevará a tu entidad a un estado inestable y, en todo momento, existe el peligro de que se produzca un cambio en otras partes del sistema de forma que no se explique por qué se está actualizando.

Entidades frente a objetos de valor

La distinción esencial entre ambos es que la identidad importa para las entidades, pero no para los objetos de valor. Los objetos de valor suelen representarse como objetos inmutables; si se cambia una propiedad de un objeto de valor, se destruye el objeto anterior y se crea uno nuevo, porque se ha cambiado la definición del objeto de valor. Así que, si un objeto es una entidad o un objeto de valor realmente depende del contexto de cómo lo estás usando dentro de tu aplicación. Eric Evans opina lo siguiente:

¿Representa un objeto algo con continuidad e identidad -algo que se rastrea a través de diferentes estados o incluso a través de diferentes implementaciones? ¿O es un atributo que describe el estado de otra cosa? Esta es la distinción básica entre una ENTIDAD y un OBJETO DE VALOR.

Servicio

Un Servicio en el Diseño Orientado al Dominio es simplemente un objeto sin estado que realiza una acción. Mientras se analiza el modelo de dominio, es posible que te encuentres con algunos aspectos del dominio que no son fáciles de mapear en objetos. En otras palabras, a veces los comportamientos del modelo de dominio no caben en los objetos del dominio. Es decir, si los combinamos con un objeto de dominio, el objeto de dominio ya no es OOP. Romperíamos la encapsulación, el principio de responsabilidad única, el bajo acoplamiento, la alta cohesión y otro aspecto importante de la POO. Por cierto, representan un comportamiento importante del dominio, por lo que no pueden ser descuidados o simplemente incorporados a alguna de las entidades u objetos de valor. En este caso, la idea de la fabricación pura según GRASP es una buena idea.

Para continuar, describiré las señales de un servicio en el Diseño Orientado al Dominio. Hay cuatro razones principales que convencen para crear un servicio:

  • La operación realizada por el servicio se refiere a un concepto del dominio que no pertenece naturalmente a una entidad u objeto de valor.
  • El servicio no tiene estado.
  • Representa un comportamiento y, por tanto, no tiene identidad.

El servicio se deriva del lenguaje ubicuo.
En el número uno, un servicio violará la POO si realiza alguna operación sobre una entidad u objeto de valor. Para evitar eso, se necesita una nueva clase que sea pura y OOP. En el número dos se trata de no tener estado; por ejemplo, con la encriptación, no importa lo que introduzcas en la entrada o lo que obtengas en la salida; siempre obtendrás datos encriptados a la salida. El servicio en sí no almacena una copia de esos datos encriptados, por lo que es apátrida. El lenguaje ubicuo es muy importante mientras haces DDD, así que debes obedecerlo no sólo en el servicio sino también en cada parte de tu proyecto.

Los servicios son un concepto útil; tienes que tener cuidado de no empujar demasiada lógica en los servicios, lo que puede conducir a modelos de dominio inexactos, confusos y anémicos con baja cohesión conceptual. En otras palabras, tu servicio no debe separar los datos, o ser almacenados en entidades, y los comportamientos. este es un anti-patrón que viola el aspecto de experto en información de la POO.

Hay diferentes tipos de servicio en el Diseño Orientado al Dominio. El servicio que pertenece a la Capa de dominio es un servicio que se utiliza para encapsular la lógica del dominio que no encaja naturalmente en ningún Objeto de dominio existente.

El servicio que pertenece a la Capa de Infraestructura se ocupa de los detalles técnicos de la infraestructura, como el correo electrónico, etc. El último es un Servicio de la Capa de Aplicación, que normalmente se utiliza para mostrar cómo el mundo exterior interactúa con su aplicación. Exactamente, de hecho, actúa como una capa de abstracción sobre tu capa de dominio y se parece a una API. Hace posible el contacto con tu modelo de dominio. Debes tener cuidado con la exposición de objetos; hacerlo directamente puede ser engorroso y llevar a abstracciones con fugas.

Conclusión

Como puede ver, la implementación del modelo de dominio no es un trabajo fácil. Por ejemplo, no es fácil decidir si se debe modelar una pieza particular de funcionalidad como un Servicio de Dominio o un Servicio de Aplicación.

Realmente se reduce al contexto de la aplicación que estás construyendo y lo que es importante para el negocio para el que lo estás construyendo. En el próximo artículo, cubriré más temas en DDD y PHP.

Espero ver sus comentarios.

Top comments (0)