2015-10-22 2 views
4

В приведенном ниже сценарииDDD - объект домена (aggreagate) с большой коллекцией другого субъекта

class Group { 
    ... 
    Set<User> users; 
    ... 
} 

, где число пользователей в 6-ти цифр, то можно с уверенностью предположить, что выполнение какой-либо операции по коллекции Неэффективное прямое использование любого ORM (JPA/Hibernate в Java, возможно, может быть обработано с помощью ExtraLazyCollection спящего режима).

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

class Group { 

    User addUser(User anUser, GroupUserService aGroupUserService){ ... } 
    void removeUser(User anUser, GroupUserService aGroupUserService){ ... } 
} 

class GroupUserService { 

    GroupRepository groupRepository; 

    User addUser(User anUser) { 
     groupRepository.addUser(anUser); 
    } 
} 

class GroupRepository { 

    User addUser(User anUser) { 
     //execute the query(JQL or native) to save the user 
    } 
} 

делает этот звук как разумное решение, не нарушая принципы DDD, есть оптимизация, которая в настоящее время по-смотрел в этом случае.

+0

Ссылки на полные объекты 'User' - это не единственный способ его моделирования - как насчет того, чтобы иметь список своих идентификаторов? Это то, что рекомендуется, когда «Пользователь» является совокупным корнем. – guillaume31

+0

Кроме того, я думаю, вы должны больше подумать о своем агрегатном дизайне на транзакционном уровне. Огромная коллекция объектов будет не только неэффективной, но также вызовет много споров в Агрегате, который ей владеет. Каждый, кто хочет редактировать «Пользователь» в заданной «Группе», должен будет инициировать транзакцию в той же «Группе», что может привести к проблемам с блокировкой, если есть много параллельных транзакций. – guillaume31

ответ

5

Кажется, у вас может отсутствовать концепция GroupMember.

GroupMember member = group.addUser(user); 
groupMemberRepository.add(member); 

Теперь, вы можете сказать, что инварианты, такие как «вы не можете иметь дублирующие членства в группе» не может быть исполнены в строго последовательном образ, потому что нет агрегатного корня, который имеет границу вокруг всех членства.

Хотя верно, что бизнес-правило не может применяться в домене, вы можете просто полагаться на уникальное ограничение в базе данных (при условии, что механизм хранения поддерживает их).

Это компромисс, который мы можем сделать, чтобы быть последовательным и оставаться практичным, а не быть пуристом.

Однако есть и другая альтернатива, но для этого потребуется углубленный анализ бизнеса. Мы часто склонны рассматривать бизнес-правила как математические модели, но реальная жизнь часто не может быть смоделирована как таковая.

Каковы риски и последствия дублирования членства? Может ли это быть просто идентифицировано и исправлено вручную? Может ли это правило быть в конечном итоге последовательным (автоматизированный процесс избавляется от дубликатов)? Как часто это могло произойти?

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

+0

В этом случае Группа, я думаю, обязана поддерживать коллекцию GroupMember. который может закончиться снова, чтобы стать огромной коллекцией, предположим, что операция как таковая должна выполняться в коллекции, где в стоимости огромна, мое решение выше. (PS: Извиняюсь за то, что я не упомянул, что мой вопрос был больше о большой коллекции, которая относится к конкретному домену Group-User, который был более примером, который я выбрал) –

+1

@SomasundaramSekar «В этом случае Группа, я думаю, обязана поддерживать Коллекция GroupMember, которая может снова оказаться огромной коллекцией «Я не понимаю, что вы имеете в виду ...Я просто показал два способа моделирования, не удерживая группу в коллекции. Решение, которое вы предлагаете, по сути, совпадает с моим первым предложением, но ваша реализация менее согласована с DDD. Вы не должны выполнять бизнес-команды против репозиториев. – plalx

+1

Подход, который я описал, может использоваться в любых отношениях ... например. 'ProductCategorization cat = product.categorize (someCategory); productCategorizationRepository.add (cat); 'Если продукт можно разделить на тысячи категорий, возможно, имеет смысл использовать этот подход. – plalx

Смежные вопросы