2010-11-01 19 views
5

Entiendo que no deberíamos cambiar directamente los elementos secundarios de una raíz de agregado, sino que deben realizarse a través de métodos en la raíz de agregado. P. ej. order.SetOrderLineQty(product, qty);Acceso a miembros agregados subclasificados

Pero, ¿y si los hijos de la raíz de agregado son algo abstracto? Imagine que tiene Car aggregate root, que contiene una lista de IWheel como parte del agregado. ¿Cómo agregaría/cambiaría las propiedades de la rueda a través de su raíz de agregado (quién no sabe nada sobre el tipo concreto de rueda que podrían ser)?

Un ejemplo más real es el siguiente: Un médico puede crear un MedicalRerport (aggregate-root), que contiene una lista de IMedicalNote (como parte del agregado de MedicalReport). IMedicalNote es una clase base/interfaz, que se subclasifica en algunas subclases concretas, p. BloodCheckNote, TemperatureNote, MineralConcentrationNote, etc. etc.

Cada subclase tiene diferentes propiedades, y todas son editables. Un agregado de MedicalReport puede contener una o más de cualquiera de estas notas. (Cada subclase nota tiene un control de usuario específica para el usuario introducir/actualizar los datos, que se muestran como paneles/pestañas debajo de la pantalla grande MedicalReport)

Mi pregunta es, ¿cómo puedo añadir/editar las propiedades de estos notas estrictamente a través de su aggregate-root (MedicalReport)? Dado que no se me permite cambiar estas propiedades notas directamente, una opción fea es mediante la exposición de todas las posibles propiedades de la nota de la raíz agregada (MedicalReport), es decir:

report.SetWhiteBloodCellCount(cellCount); 
report.SetBloodCheckComment(comment); 
report.SetTemperature(bodyPart, temperature); 
report.AddMineral(mineral, concentration); 

Cada uno de estos métodos actualizar (o crear nuevo) tenga en cuenta los elementos en su colección interna de elementos secundarios. Hay 2 problemas obvios con esto:

  1. Tenemos que definir por adelantado todas las propiedades disponibles de todas las posibles subclases IMedicalNote en el agregado-raíz. Eso no es aceptable ya que la cantidad de subclases está garantizada para crecer, depende del tipo de datos médicos que queremos capturar, que es el punto principal de la herencia en primer lugar.
  2. Puede haber varias instancias del mismo tipo de nota dentro de la lista. Esta API fallará, ya que no podemos simplemente decir report.SetBloodCheckComment(comment) y esperamos que actualice un elemento de BloodCheckNote en la lista, ya que permitimos más de un elemento de BloodCheckNote en la lista.

todavía quieren mantener todas las interacciones a estas notas a través de su agregado de la raíz, ya que tiene que controlar si todo el agregado MedicalReport es válida para ser salvo, si el total no es modificable, optimista- de grano grueso comprobación de concurrencia, etc. Pero, ¿cómo puedo hacer eso?

Respuesta

4

Me pregunto si está malinterpretando la guía sobre las raíces agregadas (o tal vez lo hice ...).

Nunca leí la guía diciendo: "el agregado debe proporcionar métodos de proxy para cada propiedad concebible de todos sus objetos agregados". Más bien, creo que dice: "el agregado controla el ciclo de vida, la identidad y las relaciones de sus objetos agregados".

Por lo tanto, es perfectamente válido para un cliente solicitar al agregado una referencia (transitoria) a uno de sus objetos y hacer algo con él.No tengo mi copia de DDD aquí para confirmar la redacción, pero que parece coherente con la DDD summary ebook (p53), que dice:

Es posible que la raíz pase a referencias internas transitorios de objetos a externos, con la condición de que los objetos externos no contengan la referencia después de que la operación haya finalizado.

Así, en sus clientes de casos pediría MedicalReport por ejemplo (s) de IMedicalNote, volver subtipos, operar sobre ellos según el caso y pasar de nuevo a la raíz si procede.

Como digo: no puedo asegurar que esté en línea con DDD, pero el sentido común dice que es una solución más escalable y flexible que tratar de reflejar cada propiedad/método de cada subtipo en la raíz agregada.

hth.

+0

Según tengo entendido, puede recuperar el objeto interno (IMedicalNote) pero solo con fines de solo lectura. No debes hacer ninguna modificación a eso. Todas las modificaciones deben hacerse a través de la raíz para que pueda controlar la integridad. Además, ¿a qué te refieres devolviéndolo a la raíz? Una vez que modificamos la propiedad del niño externamente, eso es todo, se cambia (por referencia), pasando por alto la raíz, ¿o no? ¿Qué hace exactamente "volver a la raíz"? – Sheepy

+0

Disculpas, respuesta algo ambigua. Root devuelve copias de los objetos que el cliente actualiza y vuelve a la raíz. A continuación, Root es responsable de verificar invariantes y establecer relaciones. Proporciona una división sensible de la responsabilidad: la raíz conoce las relaciones y las restricciones entre los objetos agregados, pero no necesita conocer los detalles de todos los subtipos. Los clientes pueden operar en subtipos específicos según sea necesario. Nota Es posible que Root necesite conocer algunos detalles de subtipos (por ejemplo, si debe contener exactamente un 'BloodCheckNote' pero podría tener muchos' TemperatureNote's). – sfinnie

+0

¿Quiere crear un mecanismo de clonación para que la raíz siempre devuelva un clon de cada nota secundaria cuando se accede a través del captador público de raíz? Y luego, una forma de copiar estos valores a su objeto real una vez que el cliente devuelve a estos niños a la raíz. Solo quería aclarar si eso es lo que quiso decir, porque suena como un buen trabajo. Cheers – Sheepy

Cuestiones relacionadas