tablas relacionadas relacion obtener muchos hasmany espaƱol datos consultas belongsto orm domain-driven-design aggregate aggregateroot

relacionadas - orm de laravel



Actualizar una entidad dentro de un agregado (1)

Estaba leyendo una pregunta similar sobre SO: cómo actualizar una entidad dentro de Aggregate , pero todavía no estoy seguro de cómo una interfaz de usuario debería interactuar con las entidades dentro de un agregado.

Digamos que tengo un User , con muchas Address . El usuario es la raíz agregada, mientras que la Dirección solo existe dentro del agregado.

En una interfaz web, un usuario puede editar sus direcciones. Básicamente, lo que sucede es:

  • El usuario ve una lista de direcciones en su interfaz web
  • Hace clic en una dirección y se le redirige a esta página: edit-address?user=1&address=2
  • En esta página, obtiene un formulario donde puede modificar esta dirección.

Yo decidimos omitir la raíz agregada, esto sería sencillo:

  • Cargaríamos directamente la Address con su Id
  • Lo actualizaríamos, luego lo guardaremos

Porque queremos hacerlo de la manera DDD, tenemos diferentes soluciones:

  1. O le pedimos al usuario que obtenga esta dirección por Id :

    address = user.getAddress(id);
    address.setPostCode("12345");
    address.setCity("New York");
    em.persist(user);

    El problema con este enfoque es, IMO, que la raíz agregada aún no tiene mucho más control sobre lo que se hace con la dirección. Simplemente devuelve una referencia, por lo que no es muy diferente de pasar por alto el agregado.

  2. O le decimos al agregado que actualice una dirección existente :

    user.updateAddress(id, "12345", "New York");
    em.persist(user);

    Ahora el agregado tiene control sobre lo que se hace con esta dirección, y puede tomar cualquier acción necesaria relacionada con la actualización de una dirección.

  3. O tratamos la Dirección como un objeto de valor , y no actualizamos nuestra Address , sino que la eliminamos y la volvemos a crear :

    user.removeAddress(id);
    address = new Address();
    address.setPostCode("12345");
    address.setCity("New York");
    user.addAddress(address);
    em.persist(user);

    Esta última solución se ve elegante, pero significa que una dirección no puede ser una entidad. Entonces, ¿qué sucede si debe tratarse como una entidad , por ejemplo, porque otro objeto comercial dentro del agregado tiene una referencia al mismo?

Estoy bastante seguro de que me falta algo aquí para entender correctamente el concepto agregado y cómo se usa en ejemplos de la vida real, así que no dude en dar sus comentarios.


No, no te falta nada; en la mayoría de los casos, la mejor opción sería el número 2 (aunque llamaría a ese método changeAddress luego updateAdress - la actualización parece no hacerlo) y eso independientemente de si una dirección es una Entidad o un Value Object . Con el lenguaje ubicuo , prefieres decir que el usuario cambió su dirección, así que es exactamente como debes modelarlo: es el método changeAddress que decide si las propiedades de actualización (si la dirección es una entidad) o asigna un objeto completamente nuevo (cuando es VO) )

El siguiente código de ejemplo asume el escenario más común: dirección como VO:

public void ChangeAddress(AddressParams addressParams) { // here we might include some validation address = new Address(addressParams); // here we might include additional actions related with changing address // for example marking user as required to confirm address before // next billing }

Lo que es importante en este ejemplo, es que una vez que se crea la dirección, se considera válida; no puede haber un objeto Dirección inválido en su agregado. Sin embargo, tenga en cuenta que si usted debe seguir esta muestra o no depende de su dominio real, no hay un camino a seguir. Este es el más común sin embargo.

Y sí, siempre debe realizar operaciones en sus entidades atravesando la raíz agregada; la razón de esto se dio en muchas respuestas en SO (por ejemplo, en esta Pregunta básica agregada ).

Si algo es una entidad o VO depende de los requisitos y su dominio. La mayor parte del tiempo la dirección es solo un Objeto de valor, porque no hay diferencia entre dos direcciones con los mismos valores y las direcciones tienden a no cambiar durante su vida útil. Pero de nuevo, eso es la mayor parte del tiempo y depende del dominio que estás modelando.

Otro ejemplo: para la mayoría de los dominios, un Money sería un Objeto de Valor - 10 $ es 10 $, no tiene identidad además de la cantidad. Sin embargo, si modelara un dominio que trata con dinero en un nivel de facturas, cada factura tendría su propia identidad (expresada con un número único de algún tipo) por lo que sería una Entidad.