Эргономичная структура программ в3
June 22, 2023
Я продолжаю в режиме гамак-дривен девелопмента думать над этими проблемами.
И в рамках этого думания пошёл читать Lean Architecture, в которой среди прочего описывается и Data-Context-Interaction - штука от автора MVC. Он (автор MVC) ещё жив, by the way.
Лейтмотив книги, на мой взгляд, заключается в тезисе, что системы состоят из двух частей - what-the-system-is и what-the-system-does. Очень условно - модель данных и АПИ, внезапно. Или модель предметной области и юзкейсов.
Так же в этой книге есть ещё любопытный термин - Atomic Event Architecture. Что по сути является синонимом MVC.
И утверждается, что Atomic Event Architecture заточена на разработку систем, которые обрабатывают множество (и по количеству и по типу) независимых простых событий над отдельным объектами. Пример - графический редактор (векторный, судя по всему), где взаимодействие состоит из простых операций над одним (или группой однородных) объектом - подвинуть, покрасить, покрутить и т.п.
И далее автор пишет:
In fact, the atomic event architecture has a liability in that it fattens the interfaces of the domain classes and makes them less ‘‘domainy’’ – they become hybrid homes for what-the-system-does-and-is alike.
Если вспомнить о том, что я делаю ООД на уровне модулей - это как раз то, обо что споткнулся я:
Он начал обрастать слишком большим количеством операций, предназначенных для разных ролей и юз кейсов. Кроме того, я ещё раньше стал замечать, что зачастую в модуле появляется зависимость только из-за того, что операция сильно сцепленная с состоянием модуля должна потрогать состояние соседнего модуля
И в качестве ответа автор предлагает DCI. Эта штука довольно мозголомная и плохо ложится на современные языки, поэтому под неё запилили собственный. Поэтому в чистом виде себе я её точно не возьму. Но кое-какие идеи почерпнуть можно.
Наконец, в книге вводится понятие habit - переиспользуемого кусочка юзкейса:
It can be useful to compromise here and treat authentication as a use-case-like-thing, but one that is the purview of the programmer rather than that of the business folks. We call such a pseudo-use case a habit.
Всё это приводит нас к следующему.
Во-первых, книга даёт решение второй проблемы из оригинального поста с асимметрией кода. Решение заключается в том, что у меня система по своей сути ассиметричная - по большей части состоящая из атомарных эвентов, но содержащая несколько сложных юз кейсов, затрагивающих несколько объектов.
И в этом случае симметрии можно будет добиться, только если ввести дополнительный уровень сложных юзкесов для всех операций, что в моём случае приведёт к целому слою классов, который будет на 90% состоять из одно-строчного делегирования. Что неэргономично.
Соответственно мне надо примириться с этой асимметрией и дать ей место в Эргономичной структуре програм.
Во-вторых, она даёт (в общем-то очевидный) ответ как декомпозировать "слой приложения" - по юзкейсам.
Соотвественно, у меня получается такой кандидат в третью версию эргономичной структуры програм:
Это всё пока что чисто умозрительно и ещё только предстоит проверить как реальный код ложится на эту структуру - благо за последние несколько лет у меня появилось несколько очень разных (насколько это возможно в контексте разработки бэков на Kotlin) систем для экспериментов.
Кроме того, у этой структуры уже сейчас очевидны две проблемы.
По чисто механической метрике сцепленности/связанности (кол-во связей между и внутри модулей) в3 уступает в2 - в модулях фич связанность будет нулевая, плюс в целом в системе сцепленность будет выше. Рационализировать эту переобувку в полёте мне ещё предстоит :troll:.
И "Рациональный подход к декомпозиции систем на базе эффектов", (который я кстати переименовал в "В подход к синтезу ОО-дизайна на базе эффектов" :) ) для этой структуры, кажется не сработает. Хотя я в Проекте Э немного поупражнялся в построении декомпозиции кода сложных юз кейсов на базе диаграммы - и там тоже появились два разных вида модулей. Но, справедливости ради, я это делал не по алгоритму.