Типизированные модели: как мы перестали молча терять данные

 · 2 min read

Первая версия промежуточного представления Flude писалась быстро и грязно. Мы засунули классы, интерфейсы, перечисления и переменные в один безразмерный шаблон. У этой универсальной модели было простенькое текстовое поле. Оно определяло, чем именно объект притворяется прямо сейчас.

Течь, о которой никто не знал

Один класс на все случаи жизни

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

Генерация проходила успешно, файлы создавались. Разработчики читали справочник и пытались угадать типы данных. Тихая деградация — худший сценарий при разработке инструментов. Система обманывает тебя, делая вид, что всё нормально.

Строгие контракты

Строгая архитектура данных

Мы выкинули старый код. Появились отдельные структуры для классов, методов, перечислений и параметров. Поле класса стало типизированным объектом, который железно несет в себе имя, конкретный тип и документацию. Переход дался больно. Любой участок, который по привычке обращался к полям как к тексту, моментально падал. Система наконец-то начала орать на несоответствия. Мы вычищали старые строковые обращения и переписывали шаблоны генерации. Зато появилась гарантия: если парсер нашел сложный тип, он точно доедет до финальной страницы без потерь.

Типизация убивает целый пласт тихих багов. Жесткие контракты заставляют писать предсказуемый код и освобождают голову от удержания в памяти форматов. Кстати, о наведении порядка. В следующем посте мы расскажем, как наш ИИ-аудит полез разгребать код оркестратора и нашел там шедевральную пасхалку в виде конструкции if not 0: — привет от локальной отладки.