Доменный сервис работает с базой напрямую через JPA-репозиторий Spring Data. Как применить Dependency Inversion Principle, и что именно здесь «инвертируется»?
Домен объявляет интерфейс-порт на своём языке (OrderRepository в доменном пакете), инфраструктура его реализует. Инвертируется не только стрелка зависимости, но и владение абстракцией: интерфейс принадлежит тому, кто его использует.
- Критерий хорошего порта: в нём нет слов JPA, SQL, Entity
- Spring Data-интерфейс — уже инфраструктурный, а не доменный порт
- Цена — маппинг между доменной моделью и сущностями
А ещё Гексагональная архитектура — системное применение этой идеи
Подробно
Объясни обе части принципа и сделай акцент на слове «инверсия»: разворачивается не только направление зависимости, но и владение абстракцией — интерфейс OrderRepository лежит в доменном пакете, а JdbcOrderRepository в инфраструктурном его реализует. Приведи критерий качества порта: если он говорит save/findById и возвращает JPA-сущности, деталь протекла и инверсии не произошло. Заверши разграничением DIP / DI / IoC.
Что хотят услышать
- Что именно инвертируется.
- Владение абстракцией и пакеты.
- Цена подхода.
Частые ошибки
- Считать, что достаточно завести интерфейс где угодно — важно, кому он принадлежит.
- Путать DIP с DI: внедрение конкретного класса инверсии не даёт.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Внедрять JPA-репозиторий через конструктор, а не через поле
- ✗Наследовать доменный сервис от интерфейса Spring Data
- ✗Вынести репозиторий в отдельный модуль инфраструктуры, а домен оставить зависимым от него, как и раньше
- ✓Домен объявляет порт на своём языке, инфраструктура его реализует — инвертируется и владение абстракцией
Что спросят дальше
- Где в такой схеме проходит граница транзакции?
- Не является ли интерфейс с единственной реализацией лишней абстракцией?
Разбор темы
- SOLID: пять принципов дизайна
SRP, OCP, LSP, ISP, DIP — что каждая буква значит на самом деле, как выглядит нарушение в Java-коде, чем DIP отличается от DI и IoC.
Связанные вопросы
- Сервис получает через конструктор зависимость типа PostgresOrderRepository (конкретный класс), которую внедряет Spring. Что здесь верно? Middle
- Что такое anemic domain model, чем она плоха и когда всё-таки допустима? Middle
- Что такое гексагональная архитектура (порты и адаптеры) и чем она отличается от слоистой? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.