Доступ к подклассам агрегированных членов - PullRequest
5 голосов
/ 01 ноября 2010

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

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

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

Каждый подкласс имеет разные свойства, и все они доступны для редактирования.Агрегат MedicalReport может содержать одну или несколько таких заметок.(У каждого подкласса примечаний есть определенный пользовательский элемент управления, позволяющий пользователю вводить / обновлять детали, отображаемые в виде панелей / вкладок под большим экраном MedicalReport)

У меня вопрос, как я могу добавлять / редактировать свойстваэти примечания строго через его совокупный корень (MedicalReport)?Поскольку мне не разрешено изменять эти свойства заметок напрямую, уродливым вариантом является раскрытие всех возможных свойств заметок в совокупном корне (MedicalReport), а именно:

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

Каждый из этих методов будет обновляться (или создаватьnew) отметить элементы в своей внутренней дочерней коллекции.С этим есть 2 очевидные проблемы:

  1. Мы должны заранее определить все доступные свойства всех возможных подклассов IMedicalNote в агрегатном корне.Это неприемлемо, так как количество подклассов гарантированно возрастет, зависит от типа медицинских данных, которые мы хотим получить, что является главной точкой наследования.
  2. Может быть несколько экземпляровтого же типа заметки в списке.Этот API не будет работать, так как мы не можем просто сказать report.SetBloodCheckComment(comment) и ожидать, что он обновит элемент BloodCheckNote в списке, потому что мы разрешаем более одного элемента BloodCheckNote в списке.

Я все ещехотите поддерживать все взаимодействия с этими заметками через свой агрегатный корень, так как он должен контролировать, является ли совокупный агрегат MedicalReport действительным для сохранения, является ли агрегат не поддающимся изменению, грубой проверкой оптимистического параллелизма и т. д. Но как это сделать?Я так делаю?

1 Ответ

4 голосов
/ 02 ноября 2010

Интересно, если вы неправильно истолковываете руководство относительно совокупных корней (или, может быть, я сделал ...).

Я никогда не читал руководство, в котором говорилось: «агрегат должен предоставлять прокси-методы для каждого мыслимого свойства всех его агрегированных объектов». Скорее, я думаю, что это говорит: «агрегат контролирует жизненный цикл, идентичность и взаимосвязи своих агрегированных объектов».

Так что для клиента вполне допустимо запрашивать у агрегата (временную) ссылку на один из его объектов и что-то с ним делать. У меня нет моей копии DDD, чтобы подтвердить формулировку, но это, похоже, согласуется с краткой электронной книгой DDD (p53), которая гласит:

Корень может передавать временные ссылки внутренних возражает против внешних, при условии, что внешний объекты не содержат ссылку после завершения операции.

Таким образом, в вашем случае клиенты будут запрашивать MedicalReport для экземпляра (ов) IMedicalNote, возвращать подтипы, работать с ними соответствующим образом и возвращаться к корню, если это применимо.

Как я уже сказал: не могу точно сказать, что это соответствует DDD, но здравый смысл говорит, что это более масштабируемое и гибкое решение, чем попытка отразить каждое свойство / метод каждого подтипа в совокупном корне.

НТН.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...