Как стать автором
Обновить
822.3
OTUS
Цифровые навыки от ведущих экспертов

К какому уровню это принадлежит: прикладному или домена?

Время на прочтение 3 мин
Количество просмотров 4.9K
Автор оригинала: Matthias Noback

Куда мне это поместить?

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

Будет ли она использоваться на уровне инфраструктуры? Если да, то она принадлежит к прикладному уровню.

Правило зависимости 2

Мне нравится следовать правилу зависимости (Dependency rule): уровни могут иметь только направленные внутрь зависимости. Это гарантирует, что уровни разделены. Уровень инфраструктуры (Infrastructure) может использовать службы уровня приложения (Application). Уровень приложения может использовать службы уровня домена (Domain). Теоретически инфраструктура могла бы использовать службы уровня домена, но я бы не хотел этого допускать. Я хочу, чтобы уровень приложения определял программный интерфейс/API, который может использоваться инфраструктуры уровнем. Это делает уровень домена, том числе модель домена, деталями реализации прикладного уровня. Что я считаю довольно крутым. Не нужно ничего делать с агрегатами или событиями домена; при условии, что все может быть скрыто за приложением-как-интерфейс (Application-as-an-interface).

Чтобы можно было говорить более конкретно, рассмотрим пример «покупка электронной книги». В коде он будет представлен как PurchaseEbookController, находящийся в инфраструктурном уровне, который создает объект команды PurchaseEbook, который он передает в PurchaseEbookService. Эта служба является прикладной службой, находящаяся на уровне приложения. Служба создает объект Purchase и сохраняет его с помощью PurchaseRepository, находящегося на уровне домена. Во время выполнения будет использоваться находящийся на уровне инфраструктуры PurchaseRepositoryUsingSql, который реализует интерфейс PurchaseRepository.

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

Почему прикладная служба находится на уровне приложения? Потому что она вызывается непосредственно из контроллера, то есть уровня инфраструктуры. Сама прикладная служба является частью API, определенного на уровне приложения .

Приложение-как-интерфейс или ApplicationInterface?

Это подводит нас к интересной возможности, которая носит несколько экспериментальный характер: мы можем определить API, которое прикладной уровень предлагает окружающей его инфраструктуре, как фактический interface. Например,

namespace Application;

interface ApplicationInterface
{
    public function purchaseEbook(PurchaseEbook $command): void;

    /**
     * @return EbookForList[]
     */    
    public function listAvailableEbooks(): array;
}

Этот второй метод, listAvailableEbooks(), является примером модели представления, которая также может быть доступна через ApplicationInterface.

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


Какое ключевое качество отличает успешного PHP-разработчика? — любознательность.
Чтобы решать задачи на Middle+ уровне, необходимо уметь работать с экосистемой PHP.

Приглашаем всех желающих на
бесплатное демо-занятие, в рамках которого разберем: “Какие темы и когда нужно изучать? Почему надо задавать вопросы и исследовать все вокруг?”

ЗАПИСАТЬСЯ НА ДЕМО-УРОК


Теги:
Хабы:
-2
Комментарии 1
Комментарии Комментарии 1

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS