Найти в Дзене

Граница абстракций

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

Граница абстракций

Все плюс минус знакомы с концепцией сервисов, где бизнес-операции вынесены в метод, так чтобы их можно было переиспользовать и описывать независимо от фреймворка (относительно). Кто-то даже знает понятие Service Layer как паттерн. Но вот что происходит внутри сервиса - большой вопрос. Например что делать с повторяющейся логикой, а если строить логику на событиях, а можно ли вызывать сервис из сервиса? Хочу сфокусироваться на последнем пункте.

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

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

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

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

Когда вызов допустим: если нижележащий компонент это не еще один application service, а отдельная зависимость с более низким уровнем абстракции: доменный сервис, policy-объект, репозиторий, gateway, publisher событий и так далее. Какой-нибудь сервис отправки писем хороший пример. Я, кстати, по этой причине, вообще бы не называл такие штуки сервисами, иначе происходит жесткая путаница.

А что делать, если логика действительно повторяется? В таких случаях обычно есть два пути. Первый - вынести общий кусок в отдельный компонент более низкого уровня абстракции: доменный сервис, policy-объект или другой вспомогательный объект, который не представляет собой бизнес-операцию, а реализует часть логики. Второй строить композицию через события, когда одна операция завершает свою работу и публикует событие, а другие части системы реагируют на него независимо. Хотя я был бы с этим аккуратнее, тут если доводить до крайности может получиться еще хуже.

p.s. А какой подход используется у вас?

Telegram | YouTube | Сообщество