Унификация стиля кодирования в команде – тупичок с граблями.

August 13th, 2008

Тема жёванная-пережёванная, так что я не буду подробно останавливаться на том, зачем нужен единый стиль кодирования в команде (или проекте). Основные тезисы:

  • Унифицированный стиль кодирования упрощает сопровождение кода. Это, кажется, единственная причина, зачем он вообще нужен. Все остальное, включая меньшее количество мигреней в минуту на одного эталонного разработчика, – побочные эффекты, направленные опять же на упрощение (читай – повышение эффективности) сопровождения кода.
  • Кажется, нет никакой разницы между разными стилями с точки зрения легкости понимания и написания кода. Любой выбранный стиль, будучи принят в команде упрощает сопровождение кода, при условии, что он один и используется.
  • Единственный способ выработать единый стиль – диктатура в том или ином виде. Можно месяцами спорить о том, где правильно ставить скобки, какие отступы должны быть, можно ли использовать две пустые строки в качестве разделителя и т.д. и т.п. В один прекрасный момент терпение лопается и волевым решением назначается «правильный» стиль.

И вот, скажем, ваша команда достигла этой точки: стиль выбран, в репозитории сидит куча кода, который нужно переписать в соответствии с выбранным стилем. Даже если учесть, что львиная доля правок будет носить косметический характер, их общее количество, необходимое для достижения заветной цели, очень велико. Логичное решение, которое принимает любая вменяемая команда – постепенный переход; вместе с нормальными исправлениями разработчики будут править стиль исправляемого участка кода. На этом почему-то все успокаиваются.

Далее все происходит по одному из двух сценариев:

  1. Разработчики возвращаются к насущным проблемам, все реже вспоминая про выбранный стиль (хотя и пытаясь, время от времени, ему следовать).
  2. После массовых правок кода, наиболее ретивые поклонники стиля наталкиваются на многочисленные конфликты при слиянии кода из разных веток; недолго чешут затылки, понимая, что регулярная морока с конфликтами им совсем не улыбается и решают, что ну его на фиг. Далее всё следует по сценарию №1.

Почему так случается? Очевидно потому, что факт выбора стиля никак не влияет на его интеграцию в процесс написания кода. Типичное «стиль выбран, давайте весь новый код писать в новом стиле» не работает. Аналогичная вещь случается когда пытаются вычистить все предупреждения компилятора если их количество больше 10 на каждый исходный файл проекта. В конце концов, оказывается, что есть более приоритетные задачи, а код вроде и так работает.

Что можно сделать в такой ситуации?

  • Во-первых, нужно выделить дополнительное время на правку кода. Иными словами будьте готовы, что каждое исправление будет занимать на 10% больше времени в течение N месяцев.
  • Во-вторых, нужно, чтобы соответствие вносимых правок принятому стилю контролировалось автоматически, т.е. при каждом коммите/чекине. Казалось бы это очень просто реализуется, существует множество автоматических стилизаторов кода. На практике же выясняется, что либо выбранный стиль не поддерживается ни одним из них, либо стилизатор недостаточно толерантен к вариациям стиля, исправляя то, что исправлять не следовало.
  • В-третьих, скрипты, используемые для запуска стилизатора, должны иметь гибкую систему фильтров, позволяющую задать какие файлы следует проверять, а какие должны игнорироваться при проверке. Фильтры должны храниться вместе в исходными файлами и быть доступны каждому разработчику, имеющему право коммитить/чекинить код. В самом начале должны проверяться, только новые файлы, а также существующие файлы, успешно проходящие проверку стилизатором. По мере внесения исправлений, исправленные файлы будут в список.
  • Аналогично, стилизатор должен позволять контролировать важность того или иного предупреждения. По мере уменьшения предупреждений определённого вида, их можно превратить в ошибки с тем, чтобы гарантированно избежать их появления в будущем.
  • Кроме всего прочего, в документ, описывающий выбранный стиль следует включить рекомендации о том, как избежать массовых правок кода при стилевых правках.

Вот такие вот мысли. Альтернатива всему этому – выработать иммунитет к любому, сколь угодно ужасному, стилю кода. :-)

  1. The
    August 14th, 2008 at 02:53 | #1

    Мы все решили просто – написали свой стайлер кода, который перепахивает 100% всех проектов в нужный стиль. Повесили на хоткей в студии у всех и теперь по нажатию на одну кнопку гарантированно за 1-2 секунды правится весь текущий активный проект.

    Теперь все проекты, включая старые, гарантированно в одном стиле.

  2. August 14th, 2008 at 03:41 | #2

    Под стилем имеется в виду только форматирование кода или что-то еще?

    Если форматирование, то задача почти полностью решается через автоматические стайлеры. Если что-то более нематериальное (соглашения об именовании, например, вообще не проверишь автоматически), то помогает только процедура рецензирования кода. Чем более тшательно она проводится и для чем большей доли изменений является обязательной, тем лучше будет ситуация со стилем.

    Еще может оказаться весьма полезным fxCop, надо только подобрать правильные набор проверок для конкретного проекта.

    • August 14th, 2008 at 07:38 | #3

      Под стилем имеется в виду только форматирование кода или что-то еще?

      И форматирование, и именование переменных, и использование/не использование определённых конструкций. Всего по немножку. Всё это автомитически проверить не удается, но я хочу сказать, что то, что можно проевить автоматически должно проверяться автоматически.

      Рецензирование кода, безусловно, помогает.

  3. September 2nd, 2008 at 10:39 | #4

    Мне кажется, что стили кодирования, регламентирующие написание кода с точностью до расстановки скобок и отступов – это исключительно дело автоматических утилит. Например, в Eclipse (в том числе с CDT) есть масса возможностей по настройке автоматического поддержания стиля кодирования.
    Что мне кажется действительно важным – это правила именования и ограничения на используемые конструкции.

  4. December 18th, 2008 at 00:00 | #5

    Логичное решение, которое принимает любая вменяемая команда – постепенный переход; вместе с нормальными исправлениями разработчики будут править стиль исправляемого участка кода. На этом почему-то все успокаиваются.

    Не вижу в этом ничего логичного. Открыли проект, нажали “применить стиль”, закоммитили, profit.

    Разработчики возвращаются к насущным проблемам, все реже вспоминая про выбранный стиль (хотя и пытаясь, время от времени, ему следовать).

    Автоматический проверятор на continious integration сервере не даст забыть.

    После массовых правок кода, наиболее ретивые поклонники стиля наталкиваются на многочисленные конфликты при слиянии кода из разных веток.

    Поэтому надо _везде_ применить одинаковый стиль.

    Почему так случается? Очевидно потому, что факт выбора стиля никак не влияет на его интеграцию в процесс написания кода. Типичное «стиль выбран, давайте весь новый код писать в новом стиле» не работает.

    Да откуда вы это взяли? Стиль выбирают _до_ написания кода.

    Аналогичная вещь случается когда пытаются вычистить все предупреждения компилятора если их количество больше 10 на каждый исходный файл проекта.

    Переведите их из warning’ов в error’ы. Иначе действительно на них все будут забивать.

    На практике же выясняется, что либо выбранный стиль не поддерживается ни одним из них, либо стилизатор недостаточно толерантен к вариациям стиля, исправляя то, что исправлять не следовало.

    Выберите такой стиль, который поддерживается стилизатором.

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

    Не согласуется с вашим же утверждением, что warning’и исправляться не будут. Либо error, либо конструкция является приемлемой.

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

    Зачем? Просто не надо в одном и том же коммите исправлять стиль и менять логику работы кода.

    • December 18th, 2008 at 10:17 | #6

      Не вижу в этом ничего логичного. Открыли проект, нажали “применить стиль”, закоммитили, profit.

      А вот нет кнопочки “применить стиль”, которая даёт приемлемый результат. Лучшие стилизаторы правят только 100% распознанные участки кода. Нетронутые участки кода требуют ручной правки. Худшие стилизаторы правят 100% кода, требуя последующей ручной правки всего кода.

      Автоматический проверятор на continious integration сервере не даст забыть.

      Именно. Только автоматика не ловит все.

      Поэтому надо _везде_ применить одинаковый стиль.

      Да откуда вы это взяли? Стиль выбирают _до_ написания кода.

      Это всё в теории хорошо…

      Переведите их из warning’ов в error’ы. Иначе действительно на них все будут забивать.

      Нам вообще-то еще и работать надо. Есть более еффективные способы приложить свои усилия чем вычищать ВСЕ предупреждения. Опять же, на самом деле нужно вычистить только те предупреждения, что действительно скрывают за собой проблемы. Только вот как их распознать. :-)

      Выберите такой стиль, который поддерживается стилизатором.

      Он не удобен, так как значительная часть исправлений портит код.

      Либо error, либо конструкция является приемлемой.

      Если бы компилятор мог 100% достоверно распознавать ошибки, то он бы не выдавал бы предупреждения как класс. А пока этого не случилось для предупреждений определены “уровни”, которые приблизительно отражают степень потенциальной опасности предупреждения.

      Зачем? Просто не надо в одном и том же коммите исправлять стиль и менять логику работы кода.

      Во-первых, эта и есть одно из правил, как минимизировать кол-во правок. А во-вторых, массовые правки сложно мерджить, соотв. нужно избагать массовых правок в разных ветках.

  1. August 13th, 2008 at 22:52 | #1
  2. August 14th, 2008 at 21:00 | #2
Comments are closed.