Автор, обложка и пейпер Парнаса
Новую книгу клуб выбрал голосованием. Разбирать её помогает гость Гордей из команды страхования, которая собирает весь огромный страховой ландшафт в один продукт с красивыми интерфейсами. Про автора рассказывает Александр — тот известен в computer science как один из создателей алгоритма консенсуса Raft и преподаёт в Стэнфорде курс, из которого выросла книга; поэтому вместо метафизики в ней много историй про грабли его студентов. Сам Александр захотел прочесть её целиком после часового выступления автора в Google, а сделал это примерно год назад; на голосовании клуба книга победила не сразу. Двадцать две главы поделили на четыре встречи, а на комментарии «взяли слишком много глав» ведущие отвечают: книжка небольшая, да и рассказ про управление сложностью сам должен быть простым. Запутанные стрелки на обложке участники читают как обещание: спагетти сверху превращаются во что-то аккуратное. Из введения отдельно отмечают пейпер Дэвида Парнаса 1972 года про критерии декомпозиции: два разбиения системы индексации там сравниваются по вероятным изменениям.
Первая глава описывает два подхода к борьбе со сложностью, и первый — делать код проще: единообразный нейминг, единообразное использование классов, отказ от особых случаев. Гордей вспоминает трекер, первый коммит в который сделали, когда сам он пошёл в первый класс: принеси он туда практики 2021 года, то лишь показал бы свою осведомлённость и испортил жизнь следующему, — поэтому написал, как завещали деды, статическими классами и хелперами, зато код по всему проекту читается одинаково. Один из ведущих добавляет формулировку про два способа писать программы: настолько просто, что ошибок очевидно нет, или настолько сложно, что нет очевидных ошибок; автор книги за первый и много говорит про когнитивную сложность. Вторая половина главы — про процессы: водопад в чистом виде не работал никогда, даже его автор закладывал итерации, а вычеркнутое время на дизайн даёт систему, где решения принимали не дальше чем на два дня вперёд: поддерживать её тяжело, аджайлом она не является, водопадом не стала.
Цели автора и природа сложности
Первую главу закрывают целями автора: описать природу сложности, показать, что «система сложная» — это не ощущение, и формализовать то, что сильные разработчики часто чувствуют, но объяснить не могут. Отсюда определения, техники и рассыпанные по книге красные флаги. Автор сразу оговаривается: это не обязательные правила и не серебряные пули — если техника не уменьшает сложность именно вашей системы, возможно, она не для вас, а иногда уместны прямо противоположные приёмы. Александр разворачивает мысль про интуицию: в школе на математике учили, что некрасивый результат, скорее всего, неверен; у шахматистов есть выражение «сходил рукой» — в цейтноте сильные игроки за секунды находят сильнейшие ходы, потому что тренировались всю жизнь. Если вытащить это чувство на рациональный уровень, решение можно аргументировать и объяснить другим, а не отвечать «чую, что не окей». Тренируется оно чтением чужого кода: почти в каждой книге клуба попадаются чьи-нибудь интерфейсы, например юниксовые.
Определение сложности из второй главы нравится участникам простотой: это всё, что затрудняет понимание или изменение системы; если менять её нелегко или на понимание уходит месяц — она сложная. Симптомов три. Умножение изменений: одна фича растекается по пяти-семи местам, потому что модули слишком тесно связаны. Когнитивная нагрузка: чтобы что-то сделать, надо читать документацию и писать авторам кода, в худшем случае — давно ушедшим из компании. И самое страшное — неизвестное неизвестное: грабли, о которых никто не предупредит, потому что их нигде не описали; пример из книги — синие ссылки, которые где-то однажды покрасили красным при наведении, и при перекраске сайта в зелёный об этом уже никто не вспомнит. Причин у симптомов две — зависимости и неясность. Неясность узнаётся по конфигурационному параметру со значением 10 000, про который непонятно, секунды это, миллисекунды или часы; её цену участники вспоминают на истории про самолёт, заправленный не в тех единицах: топливо кончилось посреди рейса, но, кажется, все выжили.
От тактического кода к глубоким модулям
Третья глава — «работающего кода недостаточно» — противопоставляет тактическое программирование стратегическому: в первом цель выпустить фичу быстрее, во втором — не сделать следующее изменение сложнее. Тактика продакт называет героем: он спас день сегодня, завтра и послезавтра, бизнес его обожает, инженеры ненавидят, потому что лавры ему, а разгребать им; если стилем проникается вся команда, проект уже не спасти. Автор рисует график прогресса во времени для обоих подходов, но статистики за ним нет — Александр вспоминает, как на том самом выступлении в Google автор ответил, что собрать её сложно, это его эмпирические рассуждения. Гордей спрашивает, бывало ли, что фичу физически невозможно добавить; Александр рассказывает про платформу для физлиц с трёхнедельным релизным циклом и недельным ручным регрессом: со своей командой из трёх человек он отпилил отдельную ветку на своей инфраструктуре с отбалансированным трафиком и подтягивал общий код раз в два месяца, потому что стреляло во всех местах.
Четвёртая глава про глубину: модуль прячет внутри как можно больше, а наружу отдаёт как можно более простой интерфейс; модулем автор называет и функцию, и класс, и приложение. Александр напоминает, что ту же метафору Влад Хононов распространял на сервисы, и приводит контрпример — сложную логику на function as a service: наружу торчат все вызовы и зависимости, абстракции нет. Интерфейс для автора шире сигнатуры: это и неформальная часть, которую не проверит компилятор, — как пользоваться методом и какие у него сайд-эффекты; отсюда троллинг Java с её геттерами и сеттерами, которые ничего не прячут. Пятая глава про сокрытие информации: оно упрощает интерфейс и позволяет менять модуль, не ломая соседей; красные флаги здесь — утечка информации и временная декомпозиция, когда порядок вызова функций задаёт структуру системы. Шестая объясняет, почему модули общего назначения глубже: студенты писали отдельные операции на Delete и Backspace, хотя достаточно одной — удалить заданный диапазон символов. Слайд про то, куда двигать специализированный код, оказался из восьмой главы — её разберут в следующий раз.
Что стоит унести с собой
- 01Сложность — это всё, что мешает понимать или менять систему; симптомы — умножение изменений, когнитивная нагрузка и неизвестное неизвестное, причины — зависимости и неясность.
- 02Единообразие иногда важнее современных подходов: в старом трекере гость писал в стиле прежних авторов, чтобы код всего проекта читался одинаково.
- 03Стратегическое программирование окупается даже в стартапе: знакомый Александра сразу заложил основы, нагрузочные тесты и безопасность — и прошёл due diligence легче компаний поздних стадий.
- 04Глубокий модуль прячет больше, чем показывает: интерфейс — это не только сигнатура, но и описание сайд-эффектов, а метод под один частный случай — красный флаг.