2011-08-25 12 views
6

Estaba leyendo una pregunta similar en SO: How update an entity inside Aggregate, pero todavía no estoy seguro de cómo una interfaz de usuario debería interactuar con las entidades dentro de un agregado.Actualizar una entidad dentro de un agregado

Digamos que tengo un User, con un montón de Address es. 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 ocurre es:

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

que decidimos pasar por alto la raíz agregada, esto sería sencillo:

  • Nos cargar directamente el Address con su Id
  • Nos actualizarlo, a continuación, guardarlo

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

  1. O nos preguntar al usuario a obtener 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, en mi opinión, que la raíz agregada todavía 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 decimos el agregado para actualizar 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 que va con la actualización de una dirección.

  3. O tratamos a la dirección como un objeto de valor y no actualizamos nuestra Address, sino más bien eliminarla y volver a crearla:

    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 tiene que ser tratado 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 global y cómo se utiliza en los ejemplos de la vida real, así que por favor no dude en dar a sus comentarios!

Respuesta

4

No, no estamos perdiendo algo - en la mayoría de los casos, la mejor opción sería número 2 (aunque yo diría que el método changeAddress continuación updateAdress - Actualización parece tan no-DDD) y eso es sin tener en cuenta si una dirección es una entidad u objeto de valor. Con Idioma omnipresente, diría que el usuario cambió su dirección, así que es exactamente cómo debe 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 se supone que 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 esta muestra, es que una vez que se crea Dirección, se considera válida - no puede haber una dirección no válida objeto en su conjunto. 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 de agregado - la razón para esto se dio en muchas respuestas en SO (por ejemplo en este Basic Aggregate Question).

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.

+0

Gracias. Eso tiene sentido, aunque no estoy seguro de cómo implementar un método 'changeAddress()'. El ejemplo anterior es una simplificación excesiva, y una dirección puede estar compuesta por una docena de campos, incluidos el nombre de la calle, el número del edificio, el punto 'LatLng' para la ubicación exacta en el mapa, etc.Entonces, ¿qué sugieres? Pon todos estos parámetros en los argumentos del método o crea algún tipo de objeto transitorio del formulario (¿sería un objeto 'Address' también?) Y pásalo como argumento a este método. – Benjamin

+0

He agregado el código de muestra para el escenario más común. No me preocuparía la cantidad de campos: DDD no se trata de los datos, sino de las relaciones y la complejidad de la gestión. – kstaruch

Cuestiones relacionadas