Использование ValueObjects Не Entity.
В регистрационном случае может быть введен объект значения UserName. Создайте объект Username при регистрации. Внедрить проверку в конструкторе UserName.
См. Это question и этот presentation для более подробной информации.
Edit1:
1.How обрабатывать случаи, когда различные правила проверки, применяемые для различного контекста.
Например: имя пользователя не должно содержать номера для определенного типа членов, но это необходимо для других типов участников?
Возможно, это могут быть разные методы фабрики. например UserName.forGoldenCardMember (...) или UserName.forPlainMember (...). Или введите MemberType (возможно, hierachy) для проверки UserName.
Другим альтернативным решением является использование AggregateFactory (AccountFactory в этом случае).
2.Is конструктор - единственное место, где можно поставить код проверки? Я читал онлайн о двух точках зрения: объект всегда должен быть действительным, а не всегда. Оба представляют хорошие аргументы, но любой другой подход?
Я предпочитаю действительный подход лично. Передача объекта с недопустимым значением приводит к повреждению encapsulabilty.
Edit2:
Требовать а) правила проверки бизнеса на основе контекста (различные правила пользователя для типов членов) б) держать проверки всех бизнес-правил, даже если один из них не
Палка с одноместным ответственностью с помощью Value Object (MemberType в этом случае). AggregateFactory может быть введен для упрощения прикладного уровня (более грубая гранулярность).
class AccoutFactory {
Account registerWith(Username username, MemberType type, ....) {
List<String> errors = new ArrayList<String>();
errors.addAll(type.listErrorsWith(username));
errors.add(//other error report...
if (CollectionUtils.isEmpty(errors)) {
return new Account(username,....);
} else {
throw new CannotRegisterAccountException(errors);
}
}
}
Edit3: Для вопросов в комментариях
а) Не следует ли Имя пользователя объект будет один, который имеет метод, который возвращает ошибку, как listErrorsWith()? В конце концов, это имя пользователя имеет разные правила для разных типов членов?
Мы можем проверить этот вопрос с другой точки зрения: у членов-членов есть разные правила для имени пользователя. Это может заменить if/else block в Username.listErrosWith (String, MemeberType) с полиморфизмом;
b) Если у нас есть метод в MemberType, знания не будут инкапсулированы в Username. Также мы говорим о том, чтобы убедиться, что имя пользователя всегда действительное.
Мы можем определить правильность имени пользователя без правил MemberType. Предположим, что «[email protected]» является действительным именем пользователя, он является хорошим кандидатом для члена GoldenCard, но не подходит для члена SilverCard.
c) Я все еще не вижу, как выполняется проверка, которая возвращает список ошибок, не получая список из исключения, созданного конструктором или статическим методом. Оба не выглядят идеально ИМХО.
Да, подпись listErrorsWith(): List выглядит вслепую, я бы предпочел использовать validate (имя пользователя) без возвращаемого значения (исключение throw при неудаче). Но это заставит цилтор поймать каждый шаг валидации, чтобы запустить проверки всего сразу.
Не могли бы вы опубликовать пример или два? – Hippoom
Давайте просто возьмем пример регистрации сайта. – user3054039
Давайте просто возьмем пример регистрации сайта электронной коммерции. Если регистрация клиента потребовала от клиента указать имя пользователя для учетной записи веб-сайта. Клиент будет уведомлен по электронной почте, если регистрация будет успешной (сведения о членах должны быть пересмотрены вместе с другой информацией, предоставленной во время шагов регистрации). Поскольку согласно DDD, объект Customer (представленный классом клиента) должен содержать метод проверки имени пользователя , как вызывать этот метод, если объект Customer не создается до тех пор, пока регистрация не будет рассмотрена? – user3054039