Вы, наверное, забыли, что полтора года назад в Эргономичном подходе было две проблемы (см. цитируемое сообщение), а я - нет:)
В общем я тут внезапно осознал, что гамак-дривен девелопмент сработал и я тихой сапой решил обе проблемы:)
Проблема №1
А вот как декомозировать слой приложения - я пока не знаю.
Тут сейчас ответ такой: пофиг:) Лишь бы команде было удобно ориентироваться. Можете делать так же, как сейчас раскладываете контроллеры. Может плясать от страниц/экранов/компонентов UI, можете от ролей пользователей, можете от юз кейсов, можете от ресурсов REST API.
В Trainer-Advisor, например, сейчас код приложения сначала разбит по ролям пользователей, потом по страницам/компонентам
Проблема №2
Однако на практике у меня некоторые операции ещё и другие операции дёргают. И мне это кажется нарушением принципа одного уровня абстракции.
Но я пока не могу сформулировать к каким систематическим проблемам это ведёт.
Во-первых, я сформулировал к каким систематическим проблемам это ведёт. К заметанию сложности под ковёр. И в итоге появлению таких скрытых монстров, как на картинке №1 - чтобы осознать весь масштаб трагедии этой операции, мне пришлось 4 часа методично код читать.
Во-вторых, я нашёл решение этой проблемы.
Оно состоит из двух частей:
1. Я отказался от сервисов приложений в пользу классов-операций - класс, который имеет один публичный метод, реализующий одну операцию (эндпоинт) системы и имеющий поля для всех ресурсов (гейтвеев, репозов, клиентов внешних систем), требующихся для реализации этой операции. См, например операцию регистрации терапевта в Trainer-Advisor
2. Я завёл штуки, которые сейчас называю "доменные операции" - это процедуры (Kotlin top-level function), которые нужные им ресурсы получают в качестве параметров. В том же коде регистрации терапевта надо CreateTherapistUserWorkflow заменить на процедуру
fun createTherapistUser(
usersRepo: UsersRepo,
therapistsRepo: TherapistsRepo,
usersFactory: UsersFactory,
registerTherapistRequest: RegisterTherapistReques,
password: CharSequence) {
...
}
с кодом его реализации, которая зависимости получает явно в качестве параметров. Реального публичного кода с иллюстрацией у меня пока нет, но есть картинка №2:)
В результате, для того чтобы оценить масштаб трагедии достаточно посмотреть на кол-во зависимостей класса-операции. А для того чтобы ограничить масштаб трагедии - достаточно ввести ограничение на кол-во зависимостей.
При том вы можете избегать дублирования "подопераций" и в целом ограничивать длину методов операций и вводить промежуточные уровни абстракции.
Параметры с ресурсами, конечно, придётся таскать - но это будет напоминалкой, чтобы искать возможность повысить уровень абстракции ресурсов и/или уменьшить количество вещей, которые делает операция. В примере из TA, например, пришло время завести UsersService, который скрывает за собой usersRepo и usersFactory
вин-вин-вин, я считаю:)
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code

