DDD использует репозиторий в сущности для проверки перед обновлением - PullRequest
0 голосов
/ 06 апреля 2019

Допустим, я не хочу обновлять сущность nickName of Person, с правилом, что этот никнейм используют до 5 других Persons. Как мне это сделать?

Должен ли я выполнить проверку в доменной службе перед вызовом обновления?

Или лучше передать personRepository в метод PersonEntity.update (...) и выполнить поиск и проверку внутри метода обновления сущности?


Дополнительные уточнения:

@ plalx Идея создания дополнительной сущности для выполнения этого правила умна.

Когда я читаю о DDD, я часто читаю, что передача хранилища в сущность не рекомендуется (если не зло). Вот почему я пытаюсь найти пример, где нам нужен репозиторий или какой-либо другой сервис в сущности). Я на самом деле не знаю, является ли плохой только прохождение репозитория, и обслуживание в порядке, или передача сервиса в сущность также не рекомендуется.

Давайте предположим, что это правило не такое сложное и важное бизнес-правило, и у нас может быть несколько похожих правил (настолько много, что создание дополнительной сущности для каждого правила для каждого атрибута, который мы хотим проверить, немного переоценено). Предположим, что мы можем разрешить 6 или 7 одинаковых псевдонимов в случае одновременного обновления (мы хотим ограничить их достаточно небольшим числом) и проверить

personRepository.usageOfNickname(this/person.nickname) < 5

достаточно. В таком случае, какой дизайн лучше с точки зрения DDD?

  • передача personRepository в Person Entity

    class Person { ... boolean changeNickname(newNickname, nicknameUsageService) { if (personRepository.usageOfNickname(this.nickname) < 5) { this.nickname = newNickname; return true; } else { return false; //or throw } } }

    это кажется мне наиболее очевидным и очевидным, выгода в том, что логика заключена в Сущность, но меня беспокоит это жалкое прохождение хранилища в сущность, и это чувство, что Эванс не одобряет это

  • вместо того, чтобы передавать personRepository в Person Entity, передавая personService в Person Entity (аналогично примеру @plalx) - лучше ли передавать службу в Entity, чем репозиторий?

  • выполнение валидации в сервисе аналогично примеру @plalx changePersonNickname(personId, newNickname){...}, но в примере @ plalx использование сервиса выглядит оправданным, так как он работает на двух сущностях, здесь у нас есть только одна сущность, и я боюсь, что если поместить эту логику в сервис, а не в Entity, который, по его мнению, не пойдет в сторону Anemic Domain Model и не покинет DDD.

1 Ответ

3 голосов
/ 07 апреля 2019

Или лучше передать personRepository в PersonEntity.update (...) и выполните поиск и проверку метод обновления внутренней сущности?

Это не помешало бы нарушению правила через параллелизм, поскольку, как только вы проверили personRepo.usageCountOfNickname(nickname) <= 5, оно могло измениться сразу после.

Если вам нужна строгая согласованность, вы можете ввести агрегированный корень NicknameUsage для обеспечения соблюдения этой политики. Вы бы изменили более 1 AR в транзакции, но это, вероятно, не имеет большого значения, поскольку очень маловероятно, что в любом случае будет много споров по тем же псевдонимам, верно?

1011 * Е.Г. *

changePersonNickname(personId, newNickname) {
    transaction {
        person = personRepository.personOfId(personId);

        currentNicknameUsage = nicknameUsageRepository.usageOfNickname(person.nickname);
        currentNicknameUsage.release();

        newNicknameUsage = nicknameUsageRepository.usageOfNickname(newNickname); 
        nicknameUsage.reserve(); //throws if 6 already

        person.changeNickname(newNickname);
    }
}

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

1017 * Е.Г. *

class Person {
    ...
    void changeNickname(newNickname, nicknameUsageService) {
        nicknameUsageService.reserveAndRelease(newNickname, this.nickname);
        this.nickname = newNickname;
    } 
}

Если вы хотите устранить все риски, связанные с несоответствием NicknameUsage отношениям User-Nickname, вы можете создать так, чтобы NicknameUsage был единственным объектом, отслеживающим отношения между пользователями и их псевдонимами (псевдоним не является частью * 1023). * AR вообще).

Наконец, у меня нет большого опыта с возможной последовательностью, и, надеюсь, кто-то еще пролил некоторый свет на то, что было бы правильным подходом, но если вы не хотите изменять много AR на транзакцию, то я думаю, что есть несколько стратегий, которые вы могли бы использовать ,

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

Если вы хотите предотвратить нарушения, вы также можете использовать какую-то сагу, где новый ник сначала зарезервирован, затем старый освобождается и, наконец, псевдоним человека изменяется. Будет короткий промежуток времени, когда у человека на самом деле будет 2 псевдонима с оговоркой, но никогда не будет времени, когда псевдонимы будут использоваться более 6 раз.

...