Я недавно прочитал DDD сам. Когда я попал в этот раздел, я был приятно удивлен, обнаружив, что обнаружил ту же четырехслойную архитектуру, что и Эванс. Как указал @lonelybug, доменный слой должен быть полностью изолирован от остальной системы. Однако что-то должно преобразовывать специфичные для пользовательского интерфейса значения (строки запроса, данные POST, сеанс и т. Д.) В доменные объекты. Это где прикладной уровень вступает в игру. Его задача - переводить туда и обратно между пользовательским интерфейсом, уровнем данных и доменом, эффективно скрывая домен от остальной части системы.
Сейчас я вижу много приложений ASP.NET MVC, где почти вся логика находится в контроллерах. Это неудачная попытка реализовать классическую трехслойную архитектуру. Контроллеры сложны для модульного тестирования, потому что у них очень много специфичных для пользовательского интерфейса проблем. На самом деле, написание контроллера таким образом, чтобы он не был напрямую связан со значениями «контекста Http», само по себе является серьезной проблемой. В идеале контроллер должен просто выполнять перевод, координировать работу и выплевывать ответ.
Может даже иметь смысл провести базовую проверку на прикладном уровне. Домен может предположить, что значения, входящие в него, имеют смысл (это действительный идентификатор для этого клиента и соответствует ли эта строка дате / времени). Однако проверка с использованием бизнес-логики (можно ли забронировать билет на самолет в прошлом?) Должна быть зарезервирована для уровня домена.
Мартин Фаулер на самом деле комментирует, насколько плоскими являются большинство доменных слоев в наши дни . Хотя большинство людей даже не знают, что такое прикладной уровень, он обнаруживает, что многие люди создают довольно тупые доменные объекты и сложные прикладные уровни, которые координируют работу различных доменных объектов. Я сам виноват в этом. Важно не создавать слой, потому что в какой-то книге вам сказали. Идея состоит в том, чтобы определить обязанности и разделить наш код на основе этих обязанностей. В моем случае «прикладной уровень» эволюционировал естественным образом, когда я увеличил модульное тестирование.
Исходя из моделей корпоративного дизайна Мартина Фаулера, наиболее распространенными являются следующие уровни:
Презентация - это представления, шаблоны презентаций, которые создают интерфейс взаимодействия для вашего приложения (я использую взаимодействие в том случае, если к вашему приложению обращаются другие системы через веб-службы или RMI, поэтому он может не являться пользовательским интерфейсом). Это также включает контроллеры, которые решают, как и как будут выполняться действия.
Домен - это место, где находятся ваши бизнес-правила и логика, определены модели вашего домена и т. Д.
Источник данных - это слой отображения данных (ORM) и источник данных (база данных, файловая система и т. Д.)
Как вы рисуете границы между тремя слоями:
Не размещайте специфическую логику презентации в ваших моделях или объектах домена
Не размещайте логику на своих страницах и контроллерах, т. Е. Логику для сохранения объектов в базе данных, создания соединений с базой данных и т. Д., Что сделает ваш уровень представления хрупким и трудным для тестирования
Используйте ORM, который позволяет вам отделить доступ к источнику данных и действия от модели
Следуйте принципу «тонкий контроллер - толстая модель», контроллеры предназначены для управления процессом выполнения, а не для его выполнения, подробнее на http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/ и http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model модель, представление и контроллер,
источник
Уровень домена моделирует бизнес вашего приложения. Это должна быть ваша четкая интерпретация ее правил, динамики ее компонентов и ее состояния в любой момент.
Слой приложения является «обеспокоены» определение рабочих мест , необходимых предстоит сделать для выполнения определенной задачи приложения. Главным образом, он отвечает за мандат необходимой работы домена и взаимодействует с другими (внешними или нет) сервисами.
К примеру , мое приложение финансового программного обеспечения операция пользователя для изменения состояния модельного объекта (объект , как это определенно в DDD [89]):
Но, как процесс подачи заявки, помимо всех типовых последствий этой операции, я должен отправить внутреннее сообщение другим пользователям приложения. Эта работа "организована" на прикладном уровне. Я не хотел бы, чтобы мой уровень домена думал о направлении службы обмена сообщениями. (и, конечно, это не ответственность уровня презентации). Как бы то ни было, одно можно сказать наверняка: мне нужен новый уровень, так как уровень моего домена полностью связан с основным бизнесом, а уровень представления моих презентаций - интерпретация пользовательских команд и представление результатов.
Примечания:
источник
Уровень домена должен быть спроектирован как уровень изоляции, что означает, что на бизнес-логику и правила не должны влиять какие-либо изменения кода (на уровне приложений, уровне представления и на уровне инфраструктуры).
Предполагается, что прикладной уровень предназначен для предоставления некоторых функций о том, что может делать интерфейс системы (приложения) (например, API или RESTful). Например, пользователи могут войти в систему, и в этом действии приложения (вход в систему) коды прикладного уровня будут кодами клиента для уровня домена (или уровня инфраструктуры), в котором извлекается объект домена пользователя и применяются методы этого объекта для реализации функция входа в систему.
Уровень приложения также должен быть спроектирован как уровень изоляции, а это означает, что на поведение приложения не должны влиять какие-либо изменения кода (на уровне представления, на уровне домена и на уровне инфраструктуры).
источник
Смысл доменного управляемого моделирования состоит в том, чтобы отделить существенную модель домена и обеспечить ее существование без каких-либо зависимостей от других уровней и других проблем приложений.
Это позволяет вам сосредоточиться на самом домене без отвлекающих факторов (таких как координация между пользовательским интерфейсом и постоянными службами).
источник
источник
Основной причиной этих границ является разделение интересов . Код, который обращается к хранилищу данных, должен беспокоиться только о доступе к хранилищу данных. Он не должен нести ответственность за соблюдение правил в отношении данных. Кроме того, пользовательский интерфейс должен отвечать за обновление элементов управления в пользовательском интерфейсе, получение значений из пользовательского ввода и перевод их во что-то, что может использовать уровень домена, и ничего более. Он должен вызывать операции, предоставляемые уровнем домена для выполнения любых необходимых действий (например, сохранить этот файл). Вызываемая веб-служба должна отвечать за преобразование среды передачи в то, что может использовать уровень домена, а затем вызывать уровень домена (большинство инструментов выполняют большую часть этой работы за вас).
Такое разделение при правильной реализации может дать вам возможность изменять части вашего кода, не затрагивая другие. Например, может быть необходимо изменить порядок сортировки возвращенной коллекции объектов. Поскольку вы знаете, что слой, отвечающий за манипулирование данными (обычно уровень бизнес-логики), обрабатывает эти вещи, вы можете легко определить, где необходимо изменить код. А также не нужно изменять способ извлечения из хранилища данных или любого другого приложения, использующего домен (пользовательский интерфейс и веб-служба из моего примера выше).
Конечная цель - сделать ваш код максимально простым в обслуживании.
Как примечание, некоторые вещи не могут быть помещены в определенный слой домена (например, регистрация, проверка и авторизация). Эти элементы обычно называются сквозными задачами, и в некоторых случаях их можно рассматривать как слой, который стоит сам по себе, который могут видеть и использовать все остальные слои.
Лично я считаю, что многоуровневый подход устарел, а сервисный подход лучше. У вас все еще есть четкая линия на песке относительно того, кто что делает, но это не заставляет вас быть иерархичным. Например, служба заказа на покупку, служба выставления счетов и служба доставки, с точки зрения приложения, все эти службы представляют ваш домен, и отсрочка ответственности, которую я описал выше, все еще действует в этом контексте, она только что была изменена таким образом что ваш домен существует в нескольких местах, дополнительно используя концепцию разделения интересов.
источник