Грязная архитектура

Так сложилось, что во фронтенде об архитектуре задумываются не так часто, как стоило бы. Не то чтобы я был исключением, но мне это принесло на проекте проблемы, которые я сейчас разгребаю. Мне хочется, чтобы на мои грабли наступило как можно меньше разработчиков, отсюда — этот пост.

Проблема

Современный фронтенд — сложный. Много бизнес-логики перекочевало из сервера в браузер. Сингл-пейджи, большие приложения со сложной структурой, логикой и прочим — этим добром сейчас никого не удивишь.

Но кроме сложной логики у фронта куча сопутствующих проблем типа манипуляций с DOM, ломающимися стилями, всеми ненавистным и никем не понятым каскадом и другими ништяками веб-разработки.

Ну и сроки, да. Они всегда горят. Разработчики стали той самой собакой, у которой «всё хорошо»:

“This is fine”
“This is fine”

Появились инструменты для решения проблем с рутиной. Манипуляции с DOM, запросы к серверу, обработка состояния, хранение данных — со всем этим нам стали помогать библиотеки и фреймворки.

Инструменты — это суперздорово, потому что они снимают с разработчиков нагрузку и позволяют сосредоточиться на бизнес-логике приложения. Хорошо же? Да, хорошо, но только это чё-то не работает, как задумано.

Мы всё ещё не уделяем достаточно внимания бизнес-логике, а упарываемся по модным библиотекам (привет, Реакт!) и фреймворкам (привет, Ангуляр!). И спорим, что лучше, что хуже, на чём приложения моднее.

Нам кажется, что инструменты предлагают решения для структуры проекта. Но фреймворк или библиотека не должны диктовать ни структуру проекта, ни правила общения компонентов системы друг с другом, ни что-либо ещё.

Инструмент не должен вообще ничего вам диктовать

Инструмент должен делать работу, для которой его придумали. Молоток не говорит плотнику, как ему сколачивать детали друг с другом, потому что плотник использует молоток как подручное средство.

Не должно быть никаких «Реакт-приложений» или «Редакс-приложений», потому что это инструменты. Реакт должен рисовать пиксели на экране. Редакс должен работать с состоянием. Всё.

А как надо, умник?

Мартин в «Чистой архитектуре» пишет, что ядром любой программной системы должны быть бизнес-правила, потому что любая программная система — это решение бизнес-задач.

Бизнес-правила — скелет, вокруг которого наворачивается мясо

Мясо — всё, что заточено под проект: фреймворк, веб-натив-гибрид, ватевер. И бизнес-правила по-хорошему никак не должны от этого зависеть.

Мартин пишет, что грамотная архитектура у проекта — та, при которой выбор фреймворка становится настолько неважным, что это решение можно откладывать до самого последнего момента.

Хорошая архитектура по Мартину это луковица из нескольких слоёв. Ядро — сущности, объекты, которые содержат критичные для бизнеса правила и данные для их работы. На втором уровне — юзкейсы, модели общения между пользователем и сущностями. Фреймворки находятся на самом внешнем слое.

Чистая архитектура по Мартину
Чистая архитектура по Мартину

При грамотно спроектированной архитектуре приложения, вы можете выкинуть Реакт и переписать всё за вечер на Вью. И приложение не поломается, потому что интерфейс зависит от бизнес-правил, а не наоборот.

А как же фигак-фигак и в продакшен?

Ну да, есть такое. Сроки горят, прототипы нинужны, на тесты нет времени. Плавали, знаем.

Но сейчас на проекте я вижу, насколько было бы проще и удобнее, если бы вначале я утряс и изолированно описал логику взаимодействия и свойства компонентов системы.

Кроме того, что такую систему было бы проще развивать и масштабировать, её было бы гораздо проще тестировать. Когда ядро ни от чего не зависит, то и фейков для тестирования требуется меньше. А про раздельный деплой ядра и всего остального я вообще молчу.

Сейчас вот я обновляю критичные части проекта, делая их более независимыми и выделяя их в сущности с регламентированными свойствами и правилами поведения. Это действительно делает логику работы приложения прозрачнее. Но отвязаться от выбранной изначально структуры на удивление трудно.

Ну и как тогда начать проект?

Вполне логичный вопрос. Какую структуру выбрать, куда класть файлы, как их называть, и всё такое. Если раньше фреймворк приносил с собой готовое решение, то теперь надо его придумать самим.

Но за меня на этот вопрос уже ответил Дэн Абрамов в твитере:

Всё зависит от бизнес-правил. Проектируйте, опираясь на них

Узнайте как можно больше о задаче: требования, ограничения, что может пойти не так, что и как должно работать. С этой информацией начните на бумажке описывать сущности, их свойства и правила общения.

А когда начнёте писать код, старайтесь откладывать решение о выборе инструментов до самого последнего момента. Пишите так, чтобы к ядру можно было прикрутить что угодно. Всё должно зависеть от бизнес-правил, не наоборот. Вот тогда приложение действительно будет масштабируемым и тестируемым.

Ссылки

Конспект «Чистой архитектуры»

Дэн Абрамов в твитере