Мои абстракции скрыли то, что мне нужно было видеть

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

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

Что хорошая абстракция должна делать

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

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

Что вместо этого делает неправильная абстракция

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

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

Преждевременная абстракция: обязательство до понимания

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

Абстракция — это, по сути, обязательство к определённой форме: решение о том, где проходят границы, что скрыто и что выставлено наружу, как части соотносятся друг с другом. А обязаться к форме прежде, чем поймёшь то, чему придаёшь эту форму, — надёжный способ зафиксировать неправильную форму. Хуже того, как только она встала на место, ты начинаешь строить поверх неё, и каждая новая вещь, которую ты строишь, углубляет твои вложения в структуру, которую угадали, а не познали. Преждевременная абстракция не просто рискует оказаться неправильной; она активно укореняет собственную неправильность.

Дырявые абстракции заставляют отлаживать две вещи

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

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

Цена слоя, который тебе не был нужен

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

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

Зарабатывай свои абстракции из конкретного

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

Хорошая абстракция, как я в итоге понял, открывается из конкретного, а не навязывается ему. Это сжатие вещей, которые ты уже глубоко понимаешь, а не обход их понимания. Те, что я строил именно так — поздно, неохотно, после того как конкретное научило меня, где им место, — оказались теми, что действительно держались. А те, что я строил рано, из изобретательности и эстетики, оказались теми, с которыми я потом сражался месяцами.

Более глубокий урок: абстракция управляет сложностью, но не заменяет понимания

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

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

— Никаких сигналов, никакой доходности, не является инвестиционной рекомендацией.