П. Толкачев
10Платформы и инфраструктураоктябрь 20249 минут

Архитектура и онтология

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

Архитектура программной системы выглядит как чисто техническая материя. Где провести границы модулей, что от чего отделить, какие сущности завести в базе, какой сервис владеет какими данными. За семь лет в банке я привык обращаться с этими вопросами как с инженерными, у которых есть более и менее удачные ответы, измеримые latency и стоимостью поддержки. Но чем дольше я это делаю, тем отчетливее вижу вторую сторону. За каждым таким решением прячется утверждение о мире: какие вещи существуют по отдельности, а какие связаны. Архитектура — это прикладная онтология, даже если никто не произносит такого слова на стендапе.

Граница модуля — это утверждение

Когда вы решаете, что «пользователь» и «аккаунт» — две разные сущности или одна, вы структурируете не только код. Вы утверждаете что-то о реальности, которую моделируете. Может ли у человека быть несколько аккаунтов? Перестает ли пользователь существовать, когда удален последний из них? Эти вопросы выглядят техническими, но по сути они онтологические: что считается отдельной вещью, а что — ее свойством.

В банке отвлеченность этих вопросов исчезает в первый же день. У нас была таблица users, где строка соответствовала клиенту, и была таблица договоров, где строка соответствовала продукту. Долго казалось, что человек и есть строка в users. Потом пришла интеграция с системой другого банка после покупки портфеля, и выяснилось, что один и тот же живой человек существует у нас в трех экземплярах: три client_id, три немного разных ФИО, один паспорт. Комплаенс требовал считать это одним лицом. Схема считала тремя. Спор о том, «мержить или не мержить», выглядел как задача про дедупликацию, а на деле мы решали, где в нашей вселенной проходит граница между человеком и его следами в системе.

Модель становится реальностью

Самое важное происходит потом. Однажды зафиксированная в коде модель перестает быть одним из возможных описаний и становится той реальностью, в которой живут люди. Если система не предусмотрела, что у человека бывает два гражданства, два имени в разных алфавитах, биография, которая не укладывается в одну прямую, — этих возможностей просто не будет. Не потому что они невозможны в жизни, а потому что их нет в схеме. (Это единственное «не потому… а потому», которое я себе здесь позволю, но без него тут не обойтись.)

Я видел это буквально. В админке поддержки поле «гражданство» было выпадающим списком с единственным значением. Оператор, принимая человека с двумя паспортами, физически не мог ввести второе: интерфейс не давал, а за интерфейсом стояла колонка citizenship типа varchar, не массив. Клиенту вежливо предлагали «выбрать основное». Формально мы просили человека упростить себя до размера нашей ячейки. Категории базы данных стали категориями его опыта общения с банком. Чтобы это исправить, понадобилась миграция, отдельный релиз, согласование с юристами и три недели, и все это ради того, чтобы в мире снова разрешили существовать тому, что и так существовало.

Нет нейтральной декомпозиции

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

Здесь мне обычно возражают, и возражение серьезное. У нас же есть Domain-Driven Design, bounded contexts, ubiquitous language: язык бизнеса сам диктует, где резать, инженер тут скорее переводчик, чем автор. Я много лет работал именно так и считаю этот подход честнее большинства альтернатив. Но он не устраняет проблему, он ее прячет на этаж выше. Язык предметной области — не природный факт, его тоже кто-то произнес первым: продакт, регулятор, аналитик, у которого была своя картина клиента. Когда мы аккуратно кодируем «язык бизнеса», мы кодируем и то, чей это был бизнес и кого в этом языке изначально не расслышали. DDD дисциплинирует перевод. Он не отменяет того, что переводить приходится с чьего-то диалекта.

Флаг, который прожил год

Я много лет развивал у нас Unleash, платформу фича-флагов. Флаг — это вилка в моделируемом мире: при включенном одна реальность, при выключенном другая. Предполагается, что вилка временная. На ревью мы даже договорились помечать флаги датой смерти.

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

Зачем инженеру эта оптика

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

Хотя, честно говоря, я не уверен, что эту оптику стоит носить не снимая. Иногда она мешает. Если на каждом ревью колонки помнить, что ты чертишь границы чьего-то мира, недолго и застыть, а бизнесу нужен релиз в пятницу, а не семинар по философии субъекта. Бывают дни, когда я думаю, что varchar — это просто varchar, и правильно думаю. Так что я не призываю к постоянной тревоге. Я призываю к другому: хотя бы иногда, в решениях, которые потом трудно откатить, останавливаться и спрашивать, что именно мы сейчас делаем существующим, а что — нет. Здесь моя инженерия и мое исследование сходятся плотнее всего. Разбивая систему на модули, ты выбираешь, как будет устроен ее кусок мира, и хорошо бы иногда делать этот выбор с открытыми глазами: иначе его сделает за тебя флаг, который кто-то забыл выключить.

К индексу текстов© Петр Толкачев · MMXXVI