Как справиться с проверкой сущности домена до ее сохранения? - PullRequest
5 голосов
/ 22 марта 2012

Сущность (скажем, UserEntity) имеет жесткие правила для своих свойств, и она может существовать в 2 состояниях - постоянная (что означает, что она имеет id) и предварительно сохраненная (что означает, что она не имеет id пока).

Согласно ответу на на этот вопрос о том, как обрабатывать требуемые свойства , "настоящая" UserEntity должна создаваться только с id, переданным его конструктору.

Однако, когда мне нужно создать new UserEntity из информации, отправленной браузером, я должен иметь возможность проверить информацию, прежде чем продолжить в БД.

Раньше я просто создавал пустую UserEntity (без id), устанавливал новые свойства и проверял их - но в этом новом, более безопасном способе мышления о сущностях мне не следовало бы когда-либо создавать новый UserEntity без id.

Я не хочу создавать ДВЕ места, которые знают, как проверять свойства моей UserEntity, потому что если они когда-либо изменятся (и они будут), это будет удвоить код для обновления и удвоить шансы на ошибки.

Как эффективно централизовать знания о валидации свойств моей сущности?

Примечание

Одна идея, которая у меня возникла, отражена в этом вопросе , в котором я рассматриваю хранение свойств, не связанных с состоянием, таких как электронная почта, пароль и имя, в объекте стандартизированных значений, который будет знать о правилах для его свойств, которые различные сервисы, такие как Controller, Validator и Repo или Mapper, могут использовать.

Ответы [ 5 ]

4 голосов
/ 23 марта 2012

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

в фабричном методе вы создаете новый Id и передаете его конструктору UserEntity.

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

Конечно, другой вариант заключается в том, чтов фабричном методе вы сначала проверяете параметры и только затем создаете новый Id и передаете его конструктору UserEntity.

Ицик Сабан

2 голосов
/ 27 марта 2012

Я думаю, у вас есть несколько вариантов для рассмотрения:

(1) Рассмотрим ваш первый комментарий:

Сущность (скажем, UserEntity) имеет жесткие правила для свойства, и он может существовать в 2 состояниях - сохраняется (что означает, что имеет идентификатор) и предварительно сохранен (что означает, что у него еще нет идентификатора).

Здесь вы уже упоминаете, что проверка на самом деле зависит от того, была ли сущность сохранена. Другими словами, если сущность не была сохранена, то она должна быть действительной без идентификатора. Если вы продолжите эту спецификацию домена, я считаю, что проверка должна действовать соответствующим образом (например, return isValid даже без идентификатора, если объект не был сохранен)

(2) Если вы предполагаете, что «действительный» означает, что у объекта есть идентификатор, то вам нужно будет сгенерировать идентификатор при создании. В зависимости от того, как сгенерированы ваши идентификаторы, это может быть сложно (например, сохранить в базе данных и вернуть созданный идентификатор, или как-то сгенерировать уникальные идентификаторы, или ...)

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

0 голосов
/ 24 июля 2012

Я не вижу проблемы с сохранением неверных данных. То, что является действительным или нет, является деловой заботой и иногда может зависеть от ситуации. База данных не заботится об этих бизнес-правилах.

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

0 голосов
/ 28 марта 2012

Тема о том, как правильно выполнить проверку, является чем-то серым.

Валидация обычно приводится как инвариантная и контекстная валидация. Инвариантная проверка относится к тем вещам, которые, согласно вашей проблемной области, должны присутствовать для того, чтобы ваша модель функционировала должным образом в своей предназначенной роли. Контекстная проверка относится к утверждению, что это допустимо в данном контексте использования (например, Контакту, используемому для электронной почты, нужен адрес электронной почты, но не нужен номер телефона; Контакту, используемому для рассылок по каталогу, нужен почтовый адрес, но не требуется электронная почта и т. д.).

Если вы хотите быть архитектурно чистым, то технически проблемы проверки входных данных (то, что ваши клиенты вводят в пользовательский интерфейс) и состояния данного объекта - это две разные проблемы. В идеале, ваш домен не должен знать о конкретном типе приложения, для которого он написан, и поэтому не должен быть обременен предоставлением сообщений об ошибках, подходящих для использования, прямо или косвенно, при отображении сообщений об ошибках пользователю. Это представляет собой небольшую проблему, поскольку может привести к проверке дублирующихся или повторяющихся ошибок (на стороне клиента, на стороне службы, на уровне домена), поэтому многие выбирают более прагматичный подход к большей части валидации, внешней по отношению к сущности (например, валидация модель ввода до создания объекта).

0 голосов
/ 23 марта 2012

По моему мнению, методы save () и load () должны выполнять как проверку, так и установку атрибута ID. И, кстати, сущность без атрибута Identity вовсе не является сущностью.

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

загрузка из БД, загрузка из файла или (после) сохранение в БД, такое что

если загрузка из db не удалась, отменить сохранение объекта в db / file не удастся, сбросить сущность.

Поскольку проверка - это бизнес-журнал / поведение и т. Д., И лучшим примером для этого будет

Шаблон стратегии (http://en.wikipedia.org/wiki/Strategy_pattern)

...