Ответ 1
Ключевым моментом здесь является рассмотрение того, какие классы должны иметь обязанности и, в частности, какие обязанности необходимы для создания вашей функции домена.
Объект пользовательского домена
Должна быть ответственна за то, что рассказала о своем состоянии в отношении полезных бизнес-правил вашего приложения (isAdmin()
, isBanned()
, isSuspended()
, getWarnLevel()
). Подумайте об этом объекте, таком как ведро API. Что вы хотите знать об этом? Какую полезную информацию он может рассказать? Создайте API, который отвечает на эти вопросы. Будьте осторожны, чтобы пользователь не сказал вам слишком много о ДРУГИХ объектах в системе. Это не должно быть его ответственностью.
Заботится о:
- Рассказывая о себе
- Управление собственным состоянием
Не волнует
- Сохраняется ли он.
- Как это сделано
- Любые другие объекты (если только это не агрегированный корень)
- Много других вещей
Репозиторий пользователя
Класс, ответственный за предоставление и сохранение полностью сформированного существующего Users
. Возможно, они сохраняются только в памяти во время текущего запроса. Возможно, они сохраняются в кеше. Возможно, они сохраняются в MySQL. Это не имеет значения. Все это позволяет вам получать пользователей и сохранять их. Это его ответственность. Это может, но не обязательно, знать о механизме сохранения. Он должен знать как использовать механизм сохранения.
(findById($id)
, findByEmail($email)
, findBanned()
, findByCriteria($Criteria)
- хороший кандидат для стратегии или шаблона спецификации, save($User)
, delete($User)
). Опять же, ключевым моментом здесь является создание API, который удовлетворяет бизнес-правилам домена. Вам нужно найти пользователя по электронной почте? Затем сделайте эту явную точку доступа в репозитории. Если у вас нет необходимости, то нет. Как вам нужно найти Users
? Ответьте, что с API.
Заботится о
- Предоставление вам доступа к существующим объектам пользователя на основе любых произвольных критериев
- Вызов механизма сохранения, который вы ему предоставили
Не волнует
- Как точно сохраняются объекты
User
- Создание объектов
User
- Много других вещей
Пользователь Factory
UserRepositories
предназначены для обработки существующих объектов User
, но как вы их создаете в первую очередь? С заводами. Это могут быть простые фабрики, которые просто делают одного типа пользователей. Или они могут быть абстрактными фабриками, которые создают разные типы пользователей. Это зависит от вас и от ваших системных потребностей. Опять же, подумайте о том, какой API необходим для удовлетворения бизнес-правил вашего домена: (make($type, $data)
, makeAdmin($data)
, makeMember($data)
). PHP 5.6 variadic синтаксис оператора заставит этот очиститель WAY работать с btw.
Заботится о
- Создание блестящего нового
Users
Не волнует
- Источником данных для создания этих блестящих новых
Users
- Что вы делаете с
User
после его создания. - Много других вещей
User Gateway/Mapper
Это может быть ваш фактический механизм сохранения: он может напрямую взаимодействовать с реляционной базой данных, использовать Factory и использоваться репозиторием. Он выполняет фактическую выборку БД и отображает данные в формат, который может переварить Factory. Factory не должен нести ответственность за это сопоставление, потому что он не должен иметь никакого знания исходного формата, только формат, необходимый ему для сборки объекта домена. Таким образом, ответственность за отображение лежит на Gateway/Mapper.
Заботится о
- Где
User
сохраняется или извлекается, и как - Перевод этих данных из персистенции на что-то Factory хочет
- Наверное, заботится о Factory
Не волнует
- Конкретный драйвер хранилища (например, MySQL, Postgres) - это то, где PDO входит
- Создание нового объекта
User
- Много других вещей
Теперь, по общему признанию, это выглядит намного проще, чем на самом деле. Как вы обрабатываете дочерние агрегаты (например, много Comments
, принадлежащих одному Post
)? На какой стадии вы даете их Post
? Вы даже даете им это все время или только когда вы явно запрашиваете его (например, через обратный вызов?). Это сложные вопросы, на которые у меня нет ответов, и на которые частично отвечают ваши потребности в домене в на первом месте.
ORM - сложная проблема. Доктрина и Красноречивость превосходны, но не следует строго следовать приведенной выше схеме. Это нормально. Образец выше - это руководство, а не правило. Цель состоит в том, чтобы сосредоточиться на разделении проблем и сосредоточенной ответственности. Возможно, для вашего приложения не обязательно иметь все эти слои.
Что касается проверки, существует два вида проверки:
-
Проверка ввода формы
-
Проверка объектов домена
Валидация формы обычно лучше всего выполняется с помощью класса валидатора формы и некоторых правил, определенных для данной формы. Обычно вы можете определить эти правила в любом классе строителя формы, который у вас есть (например, Form::text('first_name', array('rules' => 'required|alpha'))
). Контроллер должен принимать валидатор формы как зависимость, но не должен выполнять собственно проверку.
Проверка сборки объектов домена (например, защита целостности вашей модели) может жить либо в самом объекте домена через сеттеры, либо жить в factory. Это полностью зависит от того, как вы планируете создавать объекты домена.
Следует отметить, что у вас должны быть ОБА типы проверки: проверка формы для проверки ввода и проверка объектов домена для проверки целостности данных при создании объекта.