Сложность мира, Моделирование, Модульность

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

Сложность мира, Моделирование, Модульность
INGELLO / BUSINESS0082

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

Модель это осознанное упрощение

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

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

Модель хороша не тогда, когда в ней всё есть, а тогда, когда в ней нет ничего лишнего и есть всё необходимое.

Единственный способ понять сложное

Человеческий мозг удерживает в голове одновременно совсем немного вещей. Психологи спорят о точном числе, но все сходятся в том, что их единицы, а не сотни. А современная учётная система состоит из сотен сущностей, тысяч правил и десятков тысяч строк кода. Понять такую систему целиком невозможно. Ни мне, ни любому другому архитектору. Единственный способ с ней работать это разбить её на части, каждую из которых можно понять отдельно.

Так устроена любая сложная вещь, созданная человеком. Самолёт не проектирует один инженер: есть команда двигателя, команда крыла, команда электроники, и каждая работает со своим модулем, зная только интерфейсы, которыми он стыкуется с соседями. Город не управляется одним человеком: есть районы, службы, ведомства. Модульность это не модное слово из программирования, это способ, которым человечество вообще справляется со сложностью.

Что делает модуль хорошим

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

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

  • Хороший модуль можно объяснить одним предложением: «этот модуль отвечает за складские остатки».
  • Хороший модуль можно изменить, не трогая другие.
  • Хороший модуль можно протестировать отдельно.
  • Над хорошим модулем может работать отдельная команда, не мешая остальным.

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

Где проходят границы

Самый трудный вопрос в модульности это не «нужно ли делить», а «где резать». И здесь я всегда советую смотреть не на технику, а на бизнес. Границы модулей должны повторять границы реальных областей ответственности в компании. Продажи, склад, закупки, финансы, персонал. Если в компании есть отдел, который отвечает за что-то, скорее всего, в системе должен быть модуль, который отвечает за то же самое. Тогда изменения в бизнесе естественно ложатся на изменения в одном модуле, а не расползаются по всей системе.

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

Что делать завтра

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

Модульность заложена в основу всего, что мы делаем в Ingello. Forma устроена как набор модулей, каждый из которых отвечает за свою область: продажи, склад, закупки, найм, проекты. Fractal описывает систему моделями с явными связями, и границы модулей видны в описании ещё до генерации кода. А в Systems мы начинаем проектирование именно с того, чтобы найти правильные линии разреза. Сложность мира никуда не денется. Но её можно разложить по полкам так, что каждая полка станет понятной.