Агрегаты являются одним из самых сложных понятий в DDD. У вас есть большая часть этого права. Я предлагаю выразить концепцию в терминах «членство» в совокупности более просто, чем ввести термин «подобъекты».
Да, объект не может быть членом более чем одного агрегата. Какой из них будет последним исполнителем? Один агрегатный корень может легко сделать недействительным другой, удалив элементы и оставив других членов в другом агрегате. Вы правы, в сценариях, где объект может нуждаться в членстве в нескольких агрегатах, этот объект должен быть независимым объектом, то есть он становится корнем нового агрегата. (У него могут быть или не быть дополнительные члены, но если его нет, то, конечно, он становится собственным агрегатом одного.)
И да, это абсолютно верно, что существует агрегат для принудительного применения инвариантов. Это также отдельная единица работы или единая транзакция с точки зрения постоянства. Корневой агрегат в конечном итоге отвечает за все инварианты всего своего членства, это должно быть потому, что, например, сбой инварианта может вызвать сбой персистентности, а агрегат отвечает за поддержание агрегата как жизнеспособной единой единицы персистентной работы. .
Однако, и это тонкая и трудная часть, эта конечная ответственность НЕ подразумевает, что совокупность также является первичным исполнителем. Очень похоже на то, что мы имеем в судебной системе - суд, в конечном счете, является конечной площадкой, где определяются вопросы права и где навязывается окончательная верховенство права, инвариант исполняется. Но фактическое применение (и соблюдение) происходит на многих уровнях системы. На самом деле в хорошо организованном обществе большинство действий, навязывающих верховенство закона - обеспечение соблюдения инвариантов, должно происходить задолго до того, как вы попадете в суд, и вам даже не придется полагаться на обычное обращение в суд. (Хотя в DDD вам всегда может потребоваться, чтобы агрегатный корень выполнял окончательную инвариантную очистку, например, перед сохранением.)
То, что вы предлагаете, совершенно иное, по сути, все ваше общество, за исключением суда, заключено в тюрьму, и вы, кажется, даже предлагаете, чтобы другие не могли даже посетить, они могут только передать сообщение в суд и надеяться, что оно действует соответственно.
Давайте посмотрим, что произойдет с вашим доменом, если вы последуете предложенному пути. Цель состоит в том, чтобы создать богатую и выразительную модель предметной области. С точки зрения осмысленного вездесущего языка, вы сократили свой рабочий словарный запас только до совокупных корней. Предполагается, что к объекту должен обращаться агрегатный корень из-за инвариантов, а также потому, что если дизайн верен, сущность имеет значимую идентичность, которая вытекает из его членства в контексте его агрегатного корня. Но ваше предложение, что у сущности даже нет идентификатора типа вне его совокупного корня. Эванс, в частности, говорит, что это является частью цели совокупного корня - позволить объектам получать ссылки на члены путем обхода. Но вы не можете получить полезную ссылку, потому что другой объект даже не знает, что существуют ваши типы членов. Или вы можете изменить пространство имен, но это не лучше, если вы не разрешите обход. Теперь весь ваш домен знает о типах, но о типах объектов, которые невозможно получить.
Еще хуже то, что происходит с вашим совокупным корнем. Агрегированный корень обычно должен иметь собственную причину существования, в дополнение к сохранению агрегированной целостности. Но теперь эта личность уже не ясна. Это скрыто необходимостью иметь метод-обертку для всех различных элементов и их атрибутов. То, что вы получаете, - это совокупные корни, которые больше не имеют выразительности или даже четкой идентичности, а только большие громоздкие объекты Бога.
Ваш пример Order и OrderLine - интересный пример.Приказ не обеспечивает принудительное применение какого-либо инварианта, требуемого OrderLine от имени OrderLine.В этом случае он контролирует действие, чтобы реализовать свой собственный инвариант.Это правильное действие, чтобы поставить под контроль совокупный корень.Однако более типичные агрегаты в основном связаны с созданием и / или уничтожением объектов.
Разумеется, нет необходимости устанавливать модель, в которой все изменения в состоянии должны автоматически применяться сводным корнем, а не напрямую.На самом деле, именно поэтому часто сводный корень позволяет обходу получать ссылки на члены - поэтому внешний объект может применить изменение состояния, но в контексте, где агрегат контролирует жизненный цикл экземпляра изменяемой сущности члена.
Не только видимость, но и реальное взаимодействие с более широкой областью часто имеет фундаментальное значение для разработки богатой и выразительной модели.Агрегат служит для контроля этого доступа, но не для его полного устранения.
Надеюсь, это поможет, это сложная концепция для обсуждения.