¿Los objetos inmutables y DDD van juntos?

18

Considere un sistema que use DDD (también: cualquier sistema que use un ORM). El objetivo de cualquier sistema de manera realista, en casi todos los casos de uso, será manipular esos objetos de dominio. De lo contrario, no hay un efecto o propósito real.

La modificación de un objeto inmutable hará que genere un nuevo registro después de que el objeto persista, lo que crea una hinchazón masiva en el origen de datos (a menos que elimine registros anteriores después de las modificaciones).

Puedo ver el beneficio de usar objetos inmutables, pero en este sentido, nunca puedo ver un caso útil para usar objetos inmutables. ¿Esto esta mal?

Steven Evers
fuente

Respuestas:

16

¡La computación utilizando objetos inmutables (como en la programación funcional) no implica necesariamente persistir en cada objeto que se genera!

Steven A. Lowe
fuente
Sin embargo, no veo una instancia en la que ese escenario haga uso de objetos inmutables, por lo que estarían allí sin ningún propósito en particular. ¿Me equivoco?
Steven Evers
1
Estaba pensando que los objetos inmutables serían útiles para cálculos intermedios (en hilos paralelos)
Steven A. Lowe
11

¿Inmutable en el dominio significa que tiene que ser inmutable en la base de datos? Por ejemplo, considere lo siguiente suponiendo que el cliente siempre tenga una dirección:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

ahora se ejecuta el siguiente sql teniendo en cuenta que la identificación del cliente es 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

ahora se realiza el siguiente cambio en la dirección:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

y la capa de persistencia, siendo muy inteligente, ejecuta el siguiente sql:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

De esta manera, evita la sobrecarga de una instrucción DELETE AND INSERT separada. También creo que algunos RDBMS tienen INSERT REPLACE o algo así. MySql ha REEMPLAZADO .

andho
fuente
+1 Estoy de acuerdo con usted en el principio general: no veo por qué los objetos de dominio inmutables necesariamente deben significar filas de DB inmutables.
Andres F.
En el caso anterior, si alguna vez necesitáramos cambiar el atributo de ciudad de la clase de dirección para un cliente determinado, ¿cómo lo manejaríamos? Supongamos además que el cliente podría tener varias direcciones para que haya una relación de uno a muchos entre el cliente y las direcciones
Sudarshan
1
@Sudarshan, esta es solo una forma de hacer un 'objeto de valor inmutable', no realmente inmutable en la base de datos. Por razones de rendimiento. Cada situación debe ser manejada específicamente por supuesto. Prefiero Event Sourcing para mi dominio ahora, pero soy un poco adicto a él.
andho
@Sudarshan para responder su pregunta específicamente, simplemente ejecuta una consulta de actualización que actualiza la fila al nuevo valor. Si es uno a muchos, las direcciones tendrán algún tipo de identificador dentro de la raíz agregada del cliente que se utilizará para identificarlo de forma exclusiva en la base de datos. Luego, este identificador y customer_id se usarán para actualizar esa fila en la tabla 'dirección'.
andho
@andho "esta es solo una forma de hacer un 'objeto de valor inmutable', no realmente inmutable en la base de datos". esto realmente me
alegró el
6

En DDD, los objetos inmutables se equiparan con los objetos de valor. Estos objetos no son entidades, no tienen identidad. Por lo tanto, siempre persisto los objetos de valor como columnas de la entidad en la que están contenidos (con N / Hibernate puede usar Componentes para eso). No tienen mesa propia.

guillaume31
fuente
4

Depende de cómo se asigna el objeto inmutable en la base de datos. Si es solo un componente como DateTime (de la biblioteca Joda Time), cambiar el valor dará como resultado una actualización en lugar de una inserción. Sin embargo, si lo inmutable es más complejo y requiere una fila en una tabla, entonces tiene el problema de hinchazón.

Supongo que, aunque es un argumento débil, podría implementar una pista de auditoría de esta manera. Cada cambio en lo inmutable puede rastrearse a través de los insertos. Sin embargo, hay muchas mejores maneras de hacer esto.

En general, tener objetos de dominio inmutables (en lugar de simplemente sus componentes) parece un poco incompatible con la persistencia.

Gary Rowe
fuente
De ningún modo. Los componentes son muy útiles ya que permiten que los objetos de dominio se compongan de manera diferente a los mismos datos subyacentes. Los problemas vienen con el cumplimiento de la inmutabilidad. Personalmente, trataría los objetos de dominio como mutables (con la excepción de los campos de clave principal) y lo mantendría simple.
Gary Rowe
"En general, tener objetos de dominio inmutables (en lugar de simplemente sus componentes) parece un poco incompatible con la persistencia". En su opinión, ¿dónde necesitaríamos tener objetos de valor que no deberían modelarse como componentes (terminología de Hibernate)? --- Lo siento, había escrito mal mi último comentario y, por lo tanto, lo borré.
Sudarshan
Evite los componentes cuando una sola entidad está totalmente representada por una fila y ninguno de los datos es compartido por otro objeto de dominio.
Gary Rowe
4

Eso depende del dominio. DDD no especifica que el paradigma de programación esté orientado a objetos. Sin embargo, el paradigma orientado a objetos es muy adecuado para la aplicación típica que debe persistir en una base de datos.

DDD simplemente declara que debe construir su software en torno a un modelo de dominio que represente el problema real que el software está tratando de resolver. Si ese problema fuera, por ejemplo, matemático por naturaleza, entonces la implementación de la capa de dominio utilizando programación funcional y estructuras de datos inmutables tendría mucho sentido.

Si, por otro lado, el problema es más bien una aplicación empresarial típica, y está utilizando estructuras de objetos inmutables para todos sus objetos de dominio, entonces diría que no está siguiendo DDD. Puedo proponer al menos dos argumentos:

  • Su implementación no representa un modelo de dominio de su dominio problemático. Su dominio problemático en este caso consiste en entidades que tienen un estado para modificar. Y no es así como lo ha implementado.

  • No tienes un lenguaje omnipresente. El lenguaje y los conceptos en el modelo de dominio no siguen lo que usan los expertos en dominio.

Nota: DDD utiliza objetos inmutables cuando corresponde, solo se denominan objetos de valor.

Por lo tanto, no digo que no pueda crear una aplicación de base de datos utilizando estructuras de datos puramente funcionales, y no digo que no deba hacerlo. Simplemente no creo que pueda llamarlo DDD, dependiendo del tipo de aplicación

Pete
fuente
Peter, gran respuesta. ¿Podría echar un vistazo a mi pregunta aquí stackoverflow.com/questions/13783666/… y ayudarme a resolver mi problema? Creo que los objetos de valor inmutable son excelentes para softwares que no están relacionados con la empresa. La mayoría de los objetos de las aplicaciones empresariales son mutables en mi opinión. Imagina tener un objeto de valor anidado profundo inmutable ... ContactInfo-> PhysicalLocation-> Address y quieres actualizar el código postal ... crear el gráfico de objeto completo me parece anticristo, no solo un antipatrón. ¿Qué piensas?
Pepito Fernández
3

Si está utilizando un ORM como Hibernate / NHibernate, puede configurar su opción en cascada para eliminar automáticamente los objetos huérfanos. Si una persona tiene una dirección de objeto de valor, cuando cambie la dirección, se guardará la nueva y se eliminará la anterior porque ahora está huérfana.

Mike Rowley
fuente
0

Los objetos de valor son casi siempre inmutables en DDD y el patrón de peso mosca se puede usar para mantener la duplicación de ese objeto de valor en la memoria, al igual que .NET con cadenas. El principal inconveniente es la memoria de un lado y el otro lado es la eficiencia de la creación. Con el patrón de peso mosca, se debe hacer una comparación basada en valores para determinar si algún objeto de valor nuevo o reconstituido ya está dentro de la memoria caché de peso mosca, pero cualquier otra comparación después de ese punto generalmente se puede hacer de forma segura por referencia ya que se aplica una sola instancia. De cualquier manera, ya sea que se use o no peso mosca, los objetos de valor aún se vuelven inmutables porque solo tienen una identidad intrínseca y, por lo tanto, cambiar su valor cambiaría su identidad.

jpierson
fuente
-1

Hay otra forma de usar objetos inmutables ...

En lugar de almacenar los valores 5.0, 6.0, 7.0, 8.0 y copiar todo el registro cada vez, puede almacenar algo como esto: 5.0, +1.0, +1.0, +1.0, y luego construir una dependencia correctamente para reconstruir la secuencia 5.0 , 6.0, 7.0, 8.0. De esta manera, las pequeñas modificaciones solo requieren una pequeña cantidad de memoria ...

tp1
fuente