Все стрелки направлены вниз, поэтому изменение схемы базы данных затрагивает каждый слой над ней.
Возьмём продажу билетов в театр. Работа начинается со схемы: таблица tickets с колонками seat, performance_id, status, price. ORM создаёт по ней класс Ticket с теми же полями, геттерами и сеттерами. Правила вроде «нельзя продать уже проданное место» или «вернуть билет можно только до начала спектакля» оседают в TicketService, а иногда и в контроллере.
Мартин Фаулер называет такую модель анемичной. Объекты в ней названы по предметной области, но поведения у них почти нет, это «мешки с геттерами и сеттерами». Логика живёт в сервисах, и дизайн становится процедурным. Ты платишь за доменную модель маппингом и ORM, а её преимуществ не получаешь.
Последствия обычно такие:
- смена ORM или структуры таблиц задевает бизнес-логику, потому что она зависит от слоя данных;
- правило возврата билета трудно проверить тестом без базы;
- слои со временем начинают обходить: контроллер обращается к репозиторию напрямую, минуя сервис.
Том Хомбергс в книге «Get Your Hands Dirty on Clean Architecture» называет это проектированием от базы данных и связывает его с ORM-фреймворками. Аккуратно построенные слои, по его словам, способны отделить доменную логику от веба и хранения, но оставляют слишком много лазеек, если команда не вводит дополнительных правил.