Слои. Предметка или технология?
TL;DR: Предметка. Потому что пишем приложение по предметке, а не набрасываем технологию на предметку. Грустно, но факт.
Как разделить сырцы
Данный вопрос поднимается, когда архитектура приложения получается в виде переплетения двух совершенно разных массивов: объектов предметной области и абстракций реализации. К примеру, у меня есть сейчас сущности предметной области:
- Событие
- Юзер
- Участник(он же Юзер)
- Шаблон события
- Клуб событий(участие по умолчанию)
С другой стороны, есть технология и ее фишечки:
- Routes
- Handlers
- DB-function
- Validation
Тут связь получается p2p. Каждому событию/юзеру/etc нужен роут. На каждый роут вешается хандлер, который собственно просто вызывает слой БД. “Просто” в данном случае фальшивое. Надо проверить что входные параметры реально могут быть обработаны: указанное событие есть, юзер тоже числится, баланс у него в достатке и т.д. Все это ведет к тому, что начинают появляться все абстракции технологии для каждой сущности. И сразу встрает вопрос: кто сверху?
+ root
+-event
+-route
+-handler
+-validator
+-user
+-route
+-handler
+-validator
+-club
+-route
+-handler
+-validator
или же
+ root
+-route
+-event
+-user
+-club
+-handler
+-event
+-user
+-club
+-validator
+-event
+-user
+-club
Вроде бы разницы особо нет, по количеству одно и то же.
Как мы правим код
Когда возникают баги, то в большинстве случаев, критичными будут те, что принадлежат предметной области, потому что технологии проще предметной области, это обслуживающая часть. Поэтому, когда надо исправить подобные ошибке, лучше видеть сущность предметки сфокусированно в отношении исходников.
Reuse and DRY
Какая часть предметной области может внезапно стать частью нового проекта. Можно возразить, что есть всякие компоненты интерфейса, базовые функции, паттерны взаимодействия. Да, но это уже в некотором роде своя предметка, поэтому их надо выделять особняком в какой-нибудь utils(шутка, здесь тоже надо подходить с умом).
Т.о. лучше держать исходники, разделенные по предметке. Общие же функции/классы(совсем общие) необходимо выделать и прятать в отдельную нишу.