Accessing Subclassed Aggregate Members

Я понимаю, что мы не должны изменять дочерние элементы корневого агрегата напрямую, а вместо этого они должны выполняться с помощью методов корневого агрегата. Например, order.SetOrderLineQty (product, qty);

Но что, если потомки совокупного корня являются чем-то абстрактным? Представьте, что у вас есть совокупный корень Car, который содержит список IWheel как часть агрегата. Как бы вы добавили / изменили свойства колеса через его совокупный корень (кто ничего не знает о конкретном типе колеса)?

Более реальный пример: Врач может создать MedicalRerport (aggregate-root), который содержит список IMedicalNote (как часть агрегата MedicalReport). IMedicalNote - это базовый класс / интерфейс, который разделен на несколько конкретных подклассов, например BloodCheckNote, TemperatureNote, MineralConcentrationNote и т. Д. И т. Д.

Каждый подкласс имеет разные свойства, и все они доступны для редактирования. Агрегат MedicalReport может содержать одно или несколько из этих примечаний. (Each note subclass has a specific user-control for the user to enter/update the details, shown as panels/tabs under the big MedicalReport screen)

My question is, how can I add/edit the properties of these notes strictly via its aggregate-root (MedicalReport)? Since I am not allowed to change these notes properties directly, one ugly option is by exposing all possible note properties on the aggregate root (MedicalReport), i.e.:

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

Each of these methods will update (or create new) note items in its internal children collection. There are 2 obvious problems with this:

  1. We have to define upfront all available properties of all possible IMedicalNote subclasses on the aggregate-root. That's not acceptable as the number of subclasses is guaranteed to grow, depends on the type of medical data we want to capture, which is the whole point of the inheritance in the first-place.
  2. There can be multiple instances of the same note-type within the list. This API will fail, since we can't just say report.SetBloodCheckComment(comment) and expect it will update a BloodCheckNote item in the list, because we allow more than one BloodCheckNote items in the list.

I still want to maintain all interactions to these notes via its aggregate-root, since it has to control whether the whole MedicalReport aggregate is valid to be saved, whether the aggregate is not modifiable, coarse-grained optimistic-concurrency check, etc. But how can I do that?

5
задан Sheepy 1 November 2010 в 14:15
поделиться