Стандарты помогают разработать и продвигать общий подход к тому, как писать и структурировать код. Добиться читабельного и легко расширяемого кода непросто, в том числе потому, что многие разработчики считают, что их код неприкосновенен и не должен никем поверяться. Если вы столкнетесь с таким подходом – искореняйте его, а если люди не хотят меняться – придется с ними попрощаться.
Программирование является в большей степени творчеством, чем строгой наукой, и разработчик всегда выбирает какой-то вариант реализации из множества возможных. При этом то, что один считает логичным и естественным, для другого выглядит надуманным и неуклюжим. У программистов есть дурная привычка: если они чего-то не понимают, они просто полностью переписывают это. Слышали поговорку «Из огня да в полымя»? Поэтому всем выгодно, чтобы код было легко прочитать и понять и чтобы в нем использовались одни и те же подходы и паттерны.
Хорошая новость в том, что эта проблема давно известна. Для всех основных языков программирования существуют стандарты, поэтому вам не нужно будет изобретать велосипед. Соблюдение базовых стандартов легко обеспечить с использованием сторонних инструментов, совместимых с большинством IDE. Также существуют программы, которые можно использовать в процессе сборки приложения для автоматического анализа кода перед деплоем. SonarQube – популярный инструмент с открытым кодом, поддерживающий все распространенные языки, который находит в том числе неиспользуемые переменные, работу с неинициализированными указателями, логические тупики (области, из которых нет выхода), а также многие другие проблемы.
Стандарты кодирования касаются не только форматирования кода в текстовом файле. Они могут определять общие шаблоны проектирования – например, как взаимодействовать с базами данных или регистрировать события в журнале. Что еще более важно, они должны помогать структурировать код, определять размер функций, иерархию классов, вплоть до правил выбора названий.
Стандарты можно создавать и внедрять постепенно, шаг за шагом. Необходимо организовать постоянную проверку кода (review), и никто не должен исходить из того, что его код безупречен, включая и вас, если вы, будучи техническим директором, все еще программируете.
Код должно быть легко читать и поддерживать, и, что самое главное, в нем должно быть как можно меньше ошибок. Стандарты и ревью кода помогут вам добиться этого.
9.3. Системы контроля версий
Система контроля версий (version control system) – это централизованное хранилище и одновременно машина времени для всех ваших цифровых активов. Когда-то контроль версий использовался только большими командами программистов, но сейчас процесс разработки ПО уже невозможно представить без него, и он даже проникает в другие области, такие как Google Docs, который сохраняет историю всех изменений в ваших документах.
Системы контроля версий за годы эволюционировали от CVS до SVN и современной системы Git, наиболее популярной среди разработчиков (а сервис GitHub является одним из крупнейших репозиториев ПО с открытым исходным кодом). Тем не менее основной принцип остается неизменным: обеспечить возможность параллельной разработки как одним, так и несколькими разработчиками, чтобы для этого им не приходилось настраивать отдельные окружения для работы с разными версиями проекта. Представьте, что вы находитесь в середине масштабной разработки новой версии проекта и вам понадобилось исправить ошибку в продакшене. Для этого вам нужен будет исходный код версии, которая работает в продакшене (не содержащий никаких изменений из новой версии), чтобы надежно исправить ошибку и сделать релиз, не опасаясь, что новый код попадет наружу.
Некоторые команды не используют контроль версий. Иногда они хранят старые версии в отдельных папках или в каких-нибудь файлах в формате zip. Предлоги не использовать контроль версий бывают самыми разными – что это просто не нужно, не поддерживается для их языка программирования, замедляет работу, – но все это неправда. Основная проблема в том, что они просто боятся нового.
На верхнем уровне система контроля версий представляет собой набор отдельных репозиториев. Их можно рассматривать как простые папки с файлами, но это неправильно, потому что их возможности несравненно больше. Это скорее компоненты, блоки, из которых строится ваш проект. Каждый репозиторий полон жизни и позволяет вам путешествовать во времени, это настоящая мультивселенная, в которой одновременно доступны все ваши действия, все решения, вся эволюция каждой из частей за всю историю проекта.
Заметки с полей
Цена отсутствия контроля версий
Еще в начале своей карьеры я работал в Риме для Организации Объединенных Наций – мы писали Java-сервлеты для обработки спутниковых фотографий сельскохозяйственных земель в Африке. У них уже были CGI-скрипты, разработанные на Perl, чтобы ученые могли получать доступ к фотографиям в браузере Mozilla, и нас пригласили попробовать новый стандарт Java Servlet и посмотреть, как он будет работать при реальной нагрузке. Я провел там уже несколько месяцев, и в одну из недель усердно трудился над новым модулем, чтобы закончить его до того, как я сяду в самолет и отправлюсь домой на несколько дней. 25 с лишним лет назад у нас не было стандартов или процессов работы с кодом, не говоря уже о контроле версий. По ходу работы я сам сохранял резервные копии в отдельном сетевом каталоге (и думал, что этого более чем достаточно). Я периодически тестировал, что получается, и, в общем, один из процессов в нашем приложении удалял временные файлы (в те дни место на диске было на вес золота). Однако в спешке я что-то напутал, и он удалил все исходные файлы как локально, так и с моего резервного сетевого диска. Восстановить их я не смог, как ни пытался. Я своими руками удалил результат своего же недельного труда, и другого выхода не было, кроме как остаться на выходные и написать все заново. Эта неделя стала для меня настолько поучительной, что с тех пор подобное не повторялось.
Выбор того, что именно выносить в отдельные репозитории, зависит от множества факторов, и универсального ответа тут не существует. Следующие вопросы помогут понять, что может быть отдельным репозиторием:
• Есть ли у этого компонента отдельная функция или роль?
• Требует ли он отдельных специалистов с особым набором навыков?
• Насколько он связан с другими компонентами?
• Как делаются релизы этого компонента и всего проекта?
Старайтесь избегать слишком большого количества репозиториев, но и не стоит использовать только один, в котором лежит вообще все. Если репозиториев много, то накладные расходы, связанные с ними, оказываются слишком велики, а если их мало, становится сложно разобраться в отдельных коммитах. Это классическая дилемма Златовласки: «Не слишком горячо и не слишком холодно»[2].
Подобно тому, как файлы и папки никак не влияют на их содержимое, вложенность и детализацию данных, так же и сама по себе система контроля версий не определяет какой-либо стратегии использования – это просто подход и набор инструментов. Существует, однако, ряд общепринятых и всем понятных методик, и вы можете выбрать ту, которая лучше всего подходит для вашей команды и проекта. Вот пара примеров:
• Gitflow – использует две основные ветки: master (код в ней всегда готов к деплою) и develop. Для разработки каждой новой функции вы создаете из develop новую ветку (feature branch), изменения из которой после проверки вносятся обратно в develop. Чтобы сделать релиз, вы создаете из ветки develop новую ветку (release branch) – это то, что можно деплоить. Все изменения, попавшие в ветку релиза, надо смержить в мастер. Никакие изменения не должны вноситься напрямую ни в master, ни в develop.
• GitHub flow – более простая версия Gitflow, из основных веток в ней используется только master. Для новых функций создаются новые ветки, после ревью и тестирования изменения из них вносятся в master, и их можно деплоить.
При использовании любой методики вы можете сами определить способ интеграции с тикетной системой, правила именования веток, допустимое количество изменений или время жизни для веток, релизный цикл и т. д. Все это нужно выбирать исходя из требований вашего проекта, чтобы вспомогательные инструменты и отчеты, которые вы будете создавать для вашей системы контроля версий, были максимально эффективны.