Логика, физика, статика, динамика и не только

Междисциплинарный подход в IT: как законы логики и физики отражаются в статике и динамике кода.

Логика, физика, статика, динамика и не только
INGELLO / BUSINESS0067

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

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

Логика: фундамент, который нельзя отменить

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

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

Статика: скелет системы

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

У статики есть свойство, которое я называю статической сложностью. Чем больше сущностей, связей, слоёв и зависимостей, тем труднее систему изучить. Новый разработчик открывает проект и видит триста таблиц, тысячу классов и паутину связей между ними. Чтобы понять, как всё устроено, ему нужны недели. Статическая сложность делает систему трудноизучаемой.

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

Динамика: что происходит, когда по мосту едут

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

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

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

Устойчивая динамика

Инженеры, которые строят мосты, давно знают парадокс: мост, который совсем не гнётся, не самый прочный. Жёсткая конструкция под ветром и нагрузкой накапливает напряжение и в какой-то момент ломается. Хороший мост проектируют так, чтобы он немного гнулся, пружинил, гасил колебания и возвращался в исходное положение. Это и есть устойчивость.

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

Как этого добиться на практике?

  • Держать статику простой: меньше сущностей, меньше связей, понятные имена. Лёгкий мост проще удержать.
  • Изолировать части друг от друга: изменение в одном модуле не должно распространяться волной по всей системе.
  • Защищать логику: правила бизнеса должны жить в одном месте, а не дублироваться в десяти, чтобы при изменении нагрузки или интерфейса они оставались неизменными.
  • Наблюдать за динамикой: мониторинг, логи, метрики. Мост без датчиков напряжения рушится внезапно, мост с датчиками предупреждает заранее.
  • Проверять под нагрузкой до того, как нагрузка придёт сама.

И не только

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

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

Именно поэтому мы в Ingello так много внимания уделяем статике: Fractal генерирует структуру данных и кода по единым правилам, чтобы скелет системы был лёгким и предсказуемым. А динамику мы наблюдаем и проверяем на реальных данных, потому что только в движении видно, выдержит ли мост. Если Вы хотите понять, насколько устойчива Ваша система, спросите не «как она устроена», а «что с ней будет, если завтра нагрузка вырастет вдвое, а бизнес поменяет один процесс». Ответ на этот вопрос и есть настоящая оценка архитектуры.