Вы правильно поняли, с 2 агрегатами, но теперь вам нужно понять, почему.
Агрегат участников владеет данными и поведением участников. Что означает член, как стать участником, когда он может изменить свое имя, когда его можно разблокировать и т. Д.
Игровой агрегат владеет правилами игры и двумя игроками. В нем есть все данные, необходимые для защиты его инвариантов и отображения в пользовательском интерфейсе. Инварианты, которые он защищает:
- как минимум два разных игрока должны существовать до начала игры, и один участник может играть только один раз в одной и той же игре
- каждый игрок делает ход один за другим
- когда игрок вышел из игры, он больше не может двигаться
- и т. Д.
Для защиты второго инварианта в игре есть состояние turn
, которое является указателем на следующего игрока. Но тут возникает интересный вопрос: что такое Player, как его можно представить в коде?
Игрок является указателем на одного из Участников. В нем есть все атрибуты, которые необходимы игровому агрегату или пользовательскому интерфейсу. Игровому агрегату нужен свой идентификатор для защиты первого инварианта (для обнаружения дублирующих идентификаторов), для загрузки всех игр, в которые играет Участник, и для отображения в пользовательском интерфейсе имени Игрока, чтобы другие игроки могли знать, с кем они играют.
Игрок выглядит как сущность, потому что у него есть идентификатор и другое свойство, это имя, но это не потому, что он не владеет ни именем, ни поведением для него: когда и как член может изменить его. имя контролируется Агрегатом Участника, имя Игрока обновляется без Игрока, чтобы иметь слово об этом, возможно, в фоновом режиме.
С точки зрения Игры, игрок - это простой объект, неизменный, с идентификатором и именем как string
. Это идеальный кандидат для объекта Value.
Таким образом, хотя Элемент является Агрегированным корнем (который является типом сущности), Игрок, имеющий тот же идентификатор и имя, что и Элемент, является не сущностью, а объектом значения.