2.0 Введение к части 2: Программирование
Часть 2 посвящена повседневному ремеслу написания программ, которые многие люди могут читать, менять и которым могут доверять в течение долгой жизни. Часть 1 заложила основы того, как команды организуются и принимают решения. Эта часть обращается к самому коду: к соглашениям, которым вы следуете, к тому, как вы формируете проекты и интерфейсы, как тестируете и рецензируете свою работу, как управляете историей исходного кода и как записываете знания. Это практики, отличающие кодовую базу, ускоряющую поставку, от той, что борется с каждым изменением.
В большой команде ремесло не вопрос личного вкуса. Это способ координации. Когда сотни или тысячи инженеров, подрядчиков и преемников трогают одни и те же системы, общие соглашения и ясные контракты позволяют всем работать параллельно без постоянных столкновений. Помните, что код читают гораздо чаще, чем пишут, и значительная часть этого чтения происходит годы спустя, людьми, которых вы никогда не встретите.
В корпоративной и государственной среде ставки растут ещё. Системы регулярно переживают своих авторов на десять лет и больше. Регулирование и аудит требуют документированных свидетельств контроля. Знания должны передаваться через смену персонала и границы контрактов. Поэтому главы здесь рассматривают качество не как героизм, а как спроектированное, в значительной мере автоматизированное свойство того, как работает вся команда.
Главы этой части
2.1 Стандарты кодирования и стиль: Общие, автоматически обеспечиваемые соглашения об именовании, форматировании и идиомах, позволяющие многим авторам писать так, будто писал один аккуратный автор, чтобы рецензенты тратили внимание на проект, а не на стиль.
2.2 Принципы проектирования программ: Эвристики вроде SOLID (пять принципов объектно-ориентированного проектирования), DRY (не повторяйся), связность и сцепление, а также предметно-ориентированное проектирование (моделирование программ на языке предметной области бизнеса), рассматриваемые как инструменты с областью применимости и известными режимами отказа, а не как законы, которым нужно подчиняться.
2.3 API и проектирование интерфейсов: Проектирование контрактов, через которые встречаются системы и команды, чтобы независимые команды могли менять своё нутро, не ломая потребителей и не вынуждая к согласованному развёртыванию.
2.4 Стратегия тестирования: Осознанный выбор того, что тестировать, на каком уровне и с какой уверенностью, построение быстрой и надёжной страховочной сетки, позволяющей большой организации развёртывать часто и безопасно.
2.5 Ревью кода и сотрудничество: Рассмотрение изменений до слияния, чтобы поймать дефекты, распространить знания, обеспечить стандарты и удовлетворить контроли соответствия, сохраняя ревью быстрым и конструктивным, а не церемониальным.
2.6 Контроль версий и управление исходным кодом: Система записи каждого изменения и дисциплина ветвления, репозиториев и коммитов, сохраняющая основную ветку готовой к выпуску, историю читаемой, а след аудита целым.
2.7 Документация: Письменные знания, от руководств по началу работы до ранбуков (пошаговых эксплуатационных процедур) и журналов решений, защищающие от риска ключевого человека, ускоряющие адаптацию и передающие понимание через годы и границы контрактов.
2.8 Требования к программному обеспечению: Выявление, описание, проверка и управление тем, что программа должна делать и насколько хорошо, с прослеживаемостью, которой требует регулируемая и государственная работа.
2.9 Конструирование программного обеспечения: Ремесло создания работающих программ: минимизация сложности, конструирование под проверку и изменение, защитное программирование и дисциплинированное повторное использование.
2.10 Управление конфигурацией программного обеспечения: Идентификация, контроль и аудит каждого элемента конфигурации (любого артефакта, версии которого нужно отслеживать и контролировать) и каждого изменения, чтобы выпуски были воспроизводимы, а след аудита цел.
2.11 Качество программного обеспечения: Качество как управляемое свойство шире тестирования: модели качества, обеспечение против контроля, измерение, управление дефектами и стоимость качества.
2.12 Модели и методы разработки программ: Когда и как моделировать, охватывая структурные и поведенческие модели, формальные методы (математически обоснованные спецификацию и верификацию), прототипирование и гибкие методы, и когда моделирование напрасная трата.
2.13 Вычислительные, математические и инженерные основы: Непреходящие основы под практикой: алгоритмы и структуры данных, логика и вероятность и эмпирический инженерный метод.
2.14 Структура проекта и репозитория: Единые соглашения об организации решения и его репозитория, включая стандартные папки, точку входа README и общую конфигурацию, чтобы любой инженер мог ориентироваться в любой кодовой базе.
2.15 Отладка и устранение неполадок: Поиск и исправление дефектов как дисциплинированная, обучаемая практика воспроизведения, изоляции бинарным поиском, формулирования и проверки гипотез и фиксации каждого исправления как регрессионного теста, а не гадание и правки наугад.
2.16 Инженерия производительности: Намеренное достижение достаточной скорости программы через установку бюджетов производительности, измерение и профилирование до оптимизации, понимание алгоритмической стоимости и хвостовой задержки и защиту от регрессий, всё на уровне кода и компонентов.
2.17 Конкурентность и параллелизм: Написание корректного конкурентного кода: неизменяемость и передача сообщений по умолчанию, понимание гонок, взаимных блокировок и видимости памяти, выбор правильной синхронизации и моделей более высокого уровня и намеренное тестирование недетерминированного поведения.
2.18 Управление зависимостями и цепочкой поставок: Управление сторонним кодом, составляющим большую часть современной системы: дисциплина версий и lock-файлы, устойчивый ритм обновлений, минимальный и проверенный набор зависимостей, а также происхождение и перечень компонентов программы для надёжной цепочки поставок.
2.19 Рефакторинг и технический долг: Улучшение внутреннего устройства работающего кода за надёжным набором тестов, распознавание запахов кода и применение небольших именованных рефакторингов, использование «душащей фиги» для более крупных изменений и управление техническим долгом как видимым финансируемым портфелем, а не моральным изъяном.
2.20 Обработка ошибок и паттерны устойчивости: Осознанное решение, как код отказывает и восстанавливается: ясные контракты ошибок, выбор между немедленным отказом и безопасным отказом, повторы с отступлением и идемпотентность, предохранители и плавная деградация и никогда не молчаливое проглатывание ошибки.
2.21 Системы типов и статический анализ: Обнаружение целых классов дефектов до запуска кода через статическую и постепенную типизацию, делающую недопустимые состояния непредставимыми, и линтеры, проверки типов и анализаторы, встроенные в редактор и конвейер.
Как эти главы связаны между собой
Сквозная нить части 2 изменяемость в масштабе. Каждая практика здесь существует, чтобы позволить многим людям с уверенностью менять общую долгоживущую систему. Стандарты кодирования (2.1) и принципы проектирования (2.2) формируют код так, чтобы его можно было понять и изменить. Проектирование интерфейсов (2.3) проводит границы, позволяющие командам менять своё нутро независимо. Тестирование (2.4) даёт страховочную сетку, делающую изменения безопасными. Ревью кода (2.5) это место, где индивидуальная работа встречается с коллективным владением и где стандарты на самом деле обеспечиваются. Контроль версий (2.6) это фундамент, на котором держатся ревью, интеграция и аудит. А документация (2.7) сохраняет замысел за всем этим для тех, кто придёт позже.
Эти главы также питают остальную часть руководства. Интерфейсы и принципы проектирования отсюда становятся строительными блоками систем из части 3, особенно основ архитектуры (глава 3.1). Стратегия тестирования (2.4) и контроль версий (2.6) сырьё для автоматизированных конвейеров поставки в главе 8.1. Практики документации (2.7) напрямую связаны с ранбуками и наблюдаемостью эксплуатации, например в главе 9.2. А вся часть опирается на ценности и основы принятия решений, заложенные в части 1, превращая общие принципы в конкретное повседневное ремесло.