97 этюдов для программистов. Опыт ведущих экспертов - Пит Гудлиф
Следовательно, как ни странно, тестировщики, полные решимости найти все мелкие недостатки вашего кода, в действительности — ваши друзья.
Один бинарный файл
Стив Фримен
Мне приходилось встречать проекты, где при сборке переписывалась часть кода, чтобы для каждой среды исполнения генерировался собственный бинарный файл. Такой подход всегда излишне усложняет вещи и создает риск появления несовместимых версий при каждой установке. Как минимум при этом собирается несколько почти идентичных экземпляров программы, каждый из которых предназначен для установки в соответствующей ему среде. Возникает слишком много подвижных частей, а значит, больше возможностей для ошибки.
Однажды я работал в команде, где после каждого изменения свойства нужно было сохранять код и проводить полный цикл сборки, поэтому тестировщики простаивали всякий раз, как находилась малейшая неточность (я уже говорил, что к тому же проект собирался невероятно долго?). Работал я и в такой команде, где системные администраторы требовали полной пересборки программы при вводе ее в эксплуатацию (с помощью наших же сценариев сборки), так что невозможно было гарантировать, что в эксплуатацию попадала та версия, которая прошла тестирование. И так далее.
Правило простое: создавать единственный бинарный файл, который можно точно идентифицировать и провести через все этапы конвейера выпуска продукта. Все специфические особенности среды исполнения должны оставаться частью среды. Например, их можно хранить в контейнере с компонентами (component container), в заранее согласованном файле или в определенных папках.
Если во время сборки вашего проекта производятся манипуляции с кодом или настройки целевой среды хранятся в самом коде, значит, приложение было спроектировано недостаточно хорошо: ключевые функции приложения не отделены от функций, определяемых платформой. Или еще хуже: команда знает, как нужно поступить, но не считает внесение нужных изменений достаточно приоритетной задачей.
Бывают, конечно, исключения: иногда приходится делать сборку для нескольких вариантов целевой среды, в которых ограничения по ресурсам существенно разнятся. Однако это не относится к тем из нас (и таких большинство), кто создает приложения типа «отправить данные из базы данных на экран и обратно». Другой вариант — работа с плохо написанным унаследованным (legacy) кодом, в котором навести порядок сразу слишком тяжело. В таких случаях следует двигаться постепенно, но начинайте это движение как можно раньше.
И еще одно: храните информацию о среде выполнения в системе управления версиями, как и код. Нет ничего хуже, чем испортить конфигурацию среды и не иметь возможности узнать, какие в нее были внесены изменения. Настройки среды должны храниться в отдельном репозитории, так как они меняются с другой скоростью и по другим причинам, чем код. Некоторые команды используют для этого распределенные системы управления версиями (например, bazaar и git), поскольку в них проще сохранять в репозиторий изменения, сделанные в производственной (production) среде — а они неизбежно случаются.
Правду скажет только код
Петер Зоммерлад
В конечном счете семантика программы определяется работающим кодом. Если он есть у вас только в виде бинарного файла, его будет непросто прочесть! Однако исходный код, как правило, доступен, если это ваша собственная программа, типичная коммерческая разработка, проект с открытым исходным кодом или программа на динамически интерпретируемом языке. При чтении исходного кода смысл программы должен быть очевиден. Можно с уверенностью узнать, что делает программа, только глядя в исходный код. Даже самое точное описание технических требований не скажет всей правды: в нем содержится не детальное описание того, что фактически делает программа, а общие пожелания составителя требований. Документ с архитектурой может содержать описание планируемой архитектуры, но в нем не будут описаны нужные детали реализации. Эти документы могут устареть в сравнении с текущей реализацией… или просто потеряться. Быть может, их даже и не писали. Возможно, единственное, что осталось, — это исходный код.
Учтя все сказанное, задайте себе вопрос, насколько понятно ваш код может рассказать вам или другому программисту, что он делает.
Вы можете сказать: «О, так в моих комментариях есть все, что нужно знать». Но учтите, что комментарии — это не работающий код. Они могут вводить в заблуждение так же, как любая другая документация. Традиционно считалось, что комментарии — безусловно хорошая практика, поэтому некоторые программисты без всяких раздумий пишут обширные комментарии, даже повторяя и разъясняя в них факты, и без того очевидные из собственно кода. Это плохой способ сделать код понятным.
Если ваш код нуждается в комментариях, попробуйте провести рефакторинг так, чтобы они стали не нужны. Пространные комментарии загромождают экран, а ваша IDE может автоматически их скрывать. Если нужно пояснить изменение, сделайте это не в коде, а с помощью сообщения при сохранении кода в систему управления версиями.
Что можно сделать, чтобы ваш код действительно говорил правду и как можно яснее? Старайтесь выбирать хорошие имена. Структурируйте код с учетом сильносвязанной (cohesive) функциональности, что также облегчает выбор имен. Уменьшите (decouple) связанность кода, чтобы достичь ортогональности. Напишите автоматизированные тесты, раскрывающие запланированное поведение, и проверьте интерфейсы. Безжалостно переделывайте код, если найдете способ написать проще и лучше. Старайтесь, чтобы ваш код был как можно проще для чтения и понимания.
Относитесь к своему коду как к любому другому творческому тексту — стихотворению, эссе, записи в открытом блоге или важному электронному письму. Тщательно формулируйте то, что хотите выразить, чтобы код делал то, для чего предназначен, и как можно проще сообщал, что он делает, — так, чтобы ваши намерения были ясны, когда их нельзя уже будет узнать у вас самого.
Помните, что полезным кодом пользуются гораздо дольше, чем предполагают его авторы. Те, кто будут сопровождать ваш код, останутся вам благодарны. А если вы сами занимаетесь сопровождением, и код, с которым вы работаете, не спешит раскрыть свои тайны, как можно раньше начните применять вышеупомянутые принципы. Придайте здравый смысл коду, чтобы сохранить собственный здравый рассудок.
Возьмите сборку (и ее рефакторинг) на себя
Стив Берчук
Не столь уж редки случаи, когда команды, в целом дисциплинированно соблюдающие хорошие практики написания кода, пренебрежительно относятся к сценариям сборки. Их считают либо малозначительными, либо настолько сложными, что обслуживать их может только секта специалистов по выпуску продукта (release engineers). Если сценарии сборки сложны в сопровождении, содержат дублирование и ошибки, это приводит к проблемам того же масштаба, что и плохо спроектированный код.
Почему ответственные и грамотные разработчики считают сборку проекта некой второстепенной работой?