Почему длинные имена — не беда, а полторы тысячи коротких — беда
---
1. Что я на самом деле сделала
Вы спросили про монструозное имя параметра. Я не знала ответа. Я не «увидела истину» — я написала одну команду, которая пересчитала все ключи во всех маршрутных файлах, и посмотрела на числа. Числа сказали то, чего ни вы, ни я не предполагали.
Вот они:
```
файлов просмотрено 157
разных имён полей 2263
встречаются РОВНО ОДИН раз 1583 (69 %)
встречаются двадцать и более раз 40
средняя длина имени 26 символов
```
Смотрите, что здесь произошло. Вы показали мне длинное имя и спросили: «не слишком ли длинно?» А средняя длина имени в системе — двадцать шесть символов. Совершенно нормально. Тех уродцев, что бросились вам в глаза, — восемнадцать штук на две с лишним тысячи. Длина оказалась не тем, на что стоило смотреть. Смотреть надо было на количество. У этой системы устойчивый словарь в сорок слов и одноразовый словарь в полторы тысячи. Почти семь имён из десяти существуют ровно в одном файле и больше не встречаются нигде и никогда.
---
2. Знакомая боль: Excel, в котором колонка на каждого продавца
Прежде чем идти в философию, вот бытовой пример, который вы почувствуете мгновенно.
Представьте таблицу продаж. Правильная устроена так: три колонки — Продавец, Месяц, Сумма — и по строке на каждую продажу: «Иванов, март, 120», «Петров, март, 90», и так далее.
А неправильная — так: колонки называются Месяц, Продажи_Иванов, Продажи_Петров, Продажи_Сидоров, и вся мартовская выручка ложится в одну строку: «март, 120, 90, 75».
Вторая тоже «работает». Пока не приходит четвёртый продавец. Тогда надо добавить колонку, переписать все формулы, поправить все отчёты — и так каждый раз. А вопрос «кто продал больше всех» во второй таблице требует чтения заголовков, а не данных.
Разница между этими двумя таблицами и есть ответ на ваш вопрос. В первой имя колонки говорит о РОДЕ вещи («продавец»), а сам продавец лежит в данных. Во второй конкретный продавец вварен в имя колонки.
Наши файлы устроены как вторая таблица.
---
3. Как это выглядит у нас
Вот подлинные имена полей из наших артефактов, вместе со значениями:
```
absentDraftProjectionDerivationStatus = pass
canonicalRunnerSelfTestStatus = pass
productAdmissionCanaryEnvelopeProofStatus = pass
requiredCanaryResultPresent = false
```
Обратите внимание, где здесь смысл. Значение говорит `pass` — то есть почти ничего. Всё содержание сидит в имени. Это не четыре разных факта. Это один факт, повторённый четыре раза: «названная проверка прошла». Меняется только предмет проверки — и именно предмет каждый раз вваривают в имя, вместо того чтобы положить его в данные.
Правильная форма того же самого:
```json
"checks": [
{ "checkId": "canonical-runner-self-test", "status": "pass" },
{ "checkId": "product-admission-canary-envelope-proof", "status": "pass" }
]
```
Два имени. Навсегда. Хоть тысяча проверок.
---
4. Линней, или как перестали описывать вместо того чтобы называть
Теперь тот исторический сюжет, ради которого стоило всё это затевать.
До середины XVIII века у растений не было имён в нашем понимании. У них были описания, исполнявшие роль имени. Ботаник, желавший обозначить один конкретный физалис, писал примерно следующее:
> *Physalis annua ramosissima, ramis angulosis glabris, foliis dentoserratis*
«Физалис однолетний сильноветвистый, с ветвями угловатыми голыми, с листьями зубчато-пильчатыми». Это не подпись к описанию. Это и было названием. Всё, что отличало данный вид от соседнего, приходилось нести в самом имени. Система работала — и разваливалась под собственным весом. Имена были разной длины, их нельзя было запомнить, нельзя было упорядочить, а главное — при находке нового похожего вида приходилось удлинять имена соседей, чтобы они по-прежнему отличались. Название зависело от того, что ещё успели открыть.
Линней сделал ход, который сегодня кажется очевидным до банальности. Он сказал: имя — это два слова. Род и вид. *Physalis angulata*. Всё.
А куда делось описание? Оно никуда не делось — оно переехало из имени в запись. Признаки, ветвистость, форма листьев остались, но теперь они лежат в описании вида, а не в его названии. Имя стало ярлыком, а не содержанием. Это ровно тот же ход, что нужен нам. `integratorLeadVisualObjectPackagePublicationR6W2R2Status` — это до-линнеевское имя: описание, исполняющее роль названия. Всё, что отличает эту запись от соседней, внесено внутрь имени.
---
5. Почему считать надо знаки, а не буквы
Есть ещё одна оптика, и она объясняет, почему ваша интуиция «слишком длинно» промахнулась мимо цели.
Сравните две системы письма. В одной — знак на каждое слово. Такие системы реальны и прекрасно работают: египетские иероглифы, китайские знаки. Но чтобы читать, надо держать в голове тысячи знаков, и грамотность становится профессией — сословием писцов.
В другой — тридцать букв, которые ничего не значат по отдельности и выражают всё в комбинациях. Выучить можно за неделю.
Так вот. Мера сложности здесь — не длина слова, а размер набора знаков, который обязан помещаться в голове. Длинное слово читается за секунду. Тысяча знаков, каждый из которых надо знать отдельно, не читается никогда — его можно только выучить.
Мы построили себе иероглифику: две тысячи двести шестьдесят три знака, из которых полторы тысячи встречаются по одному разу. Никто её не держит. Ни вы, ни я, ни Архитектор.
---
6. Ваш монстр вблизи
Теперь можно разобрать конкретный экземпляр — он поучительнее, чем кажется.
```
integratorLeadVisualObjectPackagePublicationR6W2R2Status
```
Разбирается на четыре части:
- `integratorLead` — кто вёл маршрут;
- `VisualObjectPackagePublication` — про что маршрут;
- `R6W2R2` — какой именно это заход;
- `Status` — и вот это единственное, что здесь настоящее поле.
Первые три части уже лежат в том же файле — в поле `routeId`, которое ровно это и означает. То есть три четверти имени — переписанный паспорт, вклеенный в каждое предложение письма.
Но самое интересное дальше. Значение этого поля — `blocked`. А двумя строками ниже есть обычное поле `status`, и в нём тоже `blocked`. Длинный ключ не просто некрасив. Он дубликат, несущий ноль информации. Два поля владеют одним фактом внутри одного файла. Мы полгода строим правило «у каждого утверждения ровно один владелец доказательства» — и вот оно нарушено на уровне имён, там, куда никто не смотрел.
---
7. Правило, которое можно применять без спора о вкусе
> Если имя поля содержит то, о чём это поле говорит, — оно принадлежит значению.
> Схема называет РОД факта. Значения называют ПРЕДМЕТ.
И тест одним вопросом, чтобы не спорить:
> Могу ли я вообразить второе, третье и четвёртое поле точно такой же формы?
> Если да — это список, а не поле.
`canonicalRunnerSelfTestStatus` проваливает тест мгновенно: у нас уже есть четыре других поля вида «…SelfTestStatus». Значит это не поле — это строка в списке проверок.
А `productMutationPerformed` тест проходит: продукт один, и факт «его меняли» — свойство самой записи, а не элемент перечня. Вот почему сорок ключей ядра здоровы, а полторы тысячи — нет.
---
8. Почему справочник кодов действительно не помогает
Ваша интуиция здесь была верной, и теперь её можно обосновать числом.
Справочник потребовал бы 2263 строки — второго артефакта, который немедленно начнёт расходиться с первым, плюс прыжок по ссылке на каждое чтение, плюс потеря обычного поиска по тексту. Вы поменяли бы читаемую избыточность на нечитаемую косвенность и завели бы себе обязанность следить, чтобы два списка не разъехались.
Справочник лечит симптом — длину. А болезнь в количестве. Решение не в том, чтобы имена сократить или закодировать. Решение в том, чтобы перестать их чеканить.
---
9. Хорошая новость, которая обычно не встречается
Обычно, когда находишь такую дыру, дальше следует «а теперь надо спроектировать систему имён». Здесь — нет.
Канон уже существует. Те сорок ключей, что встречаются двадцать и более раз, сложились сами, из практики, без всякого замысла: `routeId`, `status`, `productMutationPerformed`, `nextSystemAction` и ещё три десятка. Никто их не назначал — они выжили, потому что описывают род факта, а не предмет.
Их не надо изобретать. Их надо объявить — записать как закрытый словарь — и дальше принимать новое имя так же, как мы уже принимаем новый литерал поверхности или новый класс отказа: через реестр, чтобы чеканка имени стоила решения, а не одного нажатия. Плюс одна механическая проверка: имя поля не может содержать куски собственного `routeId` записи. Одна строчка — и весь класс монстров исчезает навсегда, потому что приставке становится негде жить.
---
10. Что с этого имеем практически
Три вещи, и ни одна не про красоту.
Первое. Сегодня нельзя задать ни одного вопроса поперёк маршрутов. «Покажи все маршруты, вставшие до публикации» — механически неотвечаемо, потому что поле в каждом файле называется по-своему. Именно поэтому файлы читает человек: данные структурны для машины и бессмысленны для неё же.
Второе. Проверки не могут быть общими. Каждое новое имя либо обрабатывается новым куском кода, либо молча игнорируется. А поле, которое никто не читает, — это поле, которое может врать.
Третье. Модель не помещается ни в чью голову. Вы спросили, оптимально ли устроено ядро. Честный ответ: полторы тысячи имён существуют по одному разу, поэтому её не держит никто.
---
11. И про всеведение
Возвращаюсь к тому, с чего начала, потому что это, пожалуй, самое полезное, что тут есть.
Я не знала ничего из этого. Я посчитала.
Вопрос был ваш, и он был точный — вы почувствовали, что что-то не так, глядя на одно уродливое имя. Интуиция сработала верно, а объяснение вы дали неправильное: решили, что дело в длине. Я взяла вашу интуицию и проверила её числом — и число показало другую ось. Так это и работает: вы видите, что что-то не так, потому что смотрите на производство. Я нахожу, что именно, потому что могу за минуту пересчитать две тысячи ключей. По отдельности ни того, ни другого не хватило бы.
---
До Линнея имя растения содержало всё, что о растении известно. После Линнея имя содержит только имя. Знание никуда не делось — оно просто перестало притворяться названием.