А вы никогда не задумывались, почему, с одной стороны, у нас появляются всё более крутые и мощные инструменты для разработки?
На бэкенде мы можем делать микросервисы, писать офигительные SPA-приложения — но при этом будто бы сама программа становится всё хуже и хуже.

Каждый раз происходит одна и та же история: мы хотим сделать как лучше, но код в итоге всё равно превращается во что-то странное и не поддерживаемое.

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

Требования как роскошь

Как же круто, когда можно просто открыть требования и понять: вот как должна работать система, которую мы делаем.

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

А вечные баги? Они часто происходят из-за того, что эта суть нигде не зафиксирована.

Но вести требования, держать их актуальными — невыносимо больно.

Наверное, поэтому многие команды так и не приходят к их управлению. Есть задача, более-менее понятно, что делать — и ладно.

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

Почему код с этим не справляется

Теоретически, эту задачу мог бы решать и код.

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

Всё это приводит к тому, что мы уже не можем хранить требования в коде. Где-то посередине появляется API endpoint — как новая граница, и требования начинают дробиться.

И вот требования уже не в коде. Они где-то между.

Монолит как способ удержать смысл, но не панацея

В этом, кстати, одно из преимуществ монолитной архитектуры: у вас просто меньше точек разрыва бизнес-логики.

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

Когда у нас не было SPA и микросервисов (если вынести за скобки производительность и масштабируемость), мы могли довольно точно управлять бизнес-логикой: все контроллеры были на бэкенде, в одном месте.

Но даже тогда у нас были заметны швы — например, база данных. Она уже накладывает некоторые технические ограничения.

Банально: чтобы выразить связь «многие ко многим», в SQL требуется промежуточная таблица. А в реальном бизнесе такой сущности нет. Это технический компромисс.

Код — это формат компрессии требований с потерями, как JPEG

На тему хороших технических компромиссов могу рассказать одну историю:

Когда появилась задача хранить изображения так, чтобы они занимали меньше места, чем огромные BMP-файлы, инженеры задумались: а как вообще человек воспринимает картинку?

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

Наш код работает примерно так же.

У нас нет способа выразить бизнес-логику в точности один к одному. Мы сжимаем реальность до программных конструкций, стараемся сохранить главное, но часть контекста и нюансов всё равно искажаются.

Мы создаём иллюзию целостности, но это уже не оригинальная бизнес-идея — это её JPEG-версия. Сжатая. Удобная. С такими техническими компромиссами, которые, по нашему мнению, не должны мешать воспринимать суть происходящего.

Чем больше удобства — тем меньше целостности

С каждым новым уровнем удобства разработки — будь то фреймворки, микросервисы, масштабируемость — мы жертвуем целостностью мышления.

Алгоритмы становятся менее прозрачными, а требования — более размытыми.

И в какой-то момент неизбежно встаёт вопрос:

А кто вообще управляет требованиями ко всей системе?

К сожалению, до сих пор не существует идеального способа хранить требования, трассировать их до кода и обратно. А может, его и не может существовать вовсе.

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

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

Но в чём я уверен точно: Каждое упрощение разработки — это просто обмен одной сложности на другую.

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

И если не управлять этим процессом — вы в итоге получите набор фрагментов, из которых уже нельзя собрать целое.

По этой же причине подход DDD выглядит особенно привлекательно — границы сервисов проходят по границам предметной области, стараясь не разрезать одно бизнес-правило пополам.

Если вы думаете, что это проблема исключительно программирования — или вообще надуманная — просто посмотрите на компании.

Это ровно та же сложность, с которой сталкивается любой бизнес: как масштабировать систему, как делить одну маленькую компанию на гораздо более крупные отделы, чтобы всё это разнообразие продолжало работать как единое целое. Чтобы не просто исполнялись отдельные задачи — а чтобы работал бизнес в целом.

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

И в следующий раз, когда вы будете проводить границу — в коде или в структуре компании — задумайтесь:

А не разрезал ли я только что одно бизнес-правило на две части? И что можно сделать, чтобы этого не допустить.

Возможно XP, TDD, DDD, и не лучшие что есть на свете, но кажется эти ребята поняли что-то первыми, так почему бы у них не поучиться, они явно что-то знают, раз делают все не так как мы привыкли.