Обход совокупного корня для редактирования отдельных моделей

Это продолжение другого вопроса: Обход совокупного корня.

Автор этого вопроса спросил, допустимо ли в его примере обход совокупного корня. У меня тот же вопрос, но для другого варианта использования.

В нашем веб-приложении есть бэк-офис, в котором мы можем редактировать все элементы, принадлежащие общему корню:

  • Продукты (совокупный корень)
  • Опции
  • Дополнительные элементы

и т.п.

Поскольку продукт не создается со всеми его опциями в пакете, мы редактируем каждую сущность в общем корне, одну за другой, на отдельном экране. Поскольку мы находимся в системе без сохранения состояния, нам необходимо однозначно идентифицировать объект, над которым мы хотим работать, в параметрах URL. Это означает, что мы будем, например, извлекать и редактировать параметр на основе его id, а не просматривать из корня.

ИМХО, имеет смысл иметь репозиторий для каждого из них, и просто делать:

$optionRepository->find($optionId);

Вместо чего-то вроде:

foreach ($product->options as $option) {
    if ($option->id == $optionId) {
        // ok, we finally found it, we can now work on it
        // ...
        break;
    }
}

Разрушает ли это концепцию совокупных корней из доменно-ориентированного дизайна? В таком случае я был бы очень признателен, если бы узнал, как это сделать правильно.


person BenMorel    schedule 23.05.2011    source источник


Ответы (2)


Это нарушает концепцию совокупного корня. Не существует «правильного» способа сделать это. Либо вы решите просто игнорировать агрегированные корневые правила и получить доступ к объектам напрямую, либо вы решите следовать агрегированным правилам и перейти к объекту из корня. Вы можете сделать это так или иначе, на самом деле ничего другого невозможно, поэтому нет какой-либо третьей альтернативы, которая представляла бы «правильный» способ прямого доступа к объекту и по-прежнему подчинялась сводным корневым правилам.

Это вопрос выбора. Лично я бы нарушил сводные корневые правила, если бы для этого была какая-то убедительная причина. Если список не огромен, то, что вы предлагаете, вероятно, в основном удобно. Неужели это даже так удобно? Вы должны создать и поддерживать другой репозиторий и т.д.

Дело в том, что как только вы создадите этот репозиторий опций, люди будут его использовать. Где угодно и когда угодно. А тут следующий сценарий, наверняка у вас были и другие подобные ситуации. Давайте создадим еще один репозиторий. Мы сделали это там, почему не здесь? Довольно скоро у вас может быть репозиторий для каждого объекта, в конечном итоге это все равно произойдет.

Не говоря уже о том, хорошо это или плохо. Раньше я работал над приложениями, в которых не было формальных совокупных корней. Все, что я говорю, это то, что на самом деле это не нечто среднее. Если вы собираетесь их использовать вообще, вы должны быть приверженцем правил совокупных корней. Вы либо признаете совокупные корни, либо всегда следуете правилам (за исключением, возможно, исключительных обстоятельств, которых вы описали нет) , а может и вовсе их не иметь.

Последовательность, вероятно, так же важна. Я бы либо наблюдал за совокупными корнями, либо полностью избавился бы от потенциального бремени, которое они могут представлять.

person Sisyphus    schedule 24.05.2011
comment
Спасибо, я понял вашу точку зрения. Предлагаете ли вы какой-либо другой подход для поиска точного элемента при просмотре из общего корня? - person BenMorel; 24.05.2011
comment
Нет, вы мало что можете сделать. Вы можете написать несколько вспомогательных методов, чтобы фактический ход обхода объектов, перечисления списков и т. д. был скрыт, а вызывающие вызывающие объекты выполняли какой-то простой метод get, но в конце дня вы все еще проходите агрегат из корня. - person Sisyphus; 25.05.2011

Если вы не будете загружать объекты из корня агрегата, вы не сможете применять агрегатные инварианты (например, продукт не должен иметь более одного параметра типа A). В результате ваши данные могут быть несогласованными.

person xelibrion    schedule 24.05.2011
comment
Это имеет смысл. Любая другая идея для обеспечения соблюдения этих правил при редактировании одного объекта глубоко в дереве агрегатов? - person BenMorel; 24.05.2011
comment
Здесь не может быть другого способа сделать это, используя доменно-ориентированный дизайн. Хотя вы можете применить эти инварианты с помощью запроса к базе данных, это означает, что вы переместили бизнес-логику за пределы домена. Этот подход нарушает дизайн, ориентированный на предметную область, и приводит к приложениям, управляемым данными. - person xelibrion; 24.05.2011