Теория чистого кода. Стиль кодирования

Чистый код должен быть эффективным, простым для восприятия и сопровождения, гибким и надежным. Приведенные требования зачастую противоречат друг другу, поэтому для написания чистого кода в каждом конкретном случае надо идти на некоторый компромисс. Нередко опытные программисты пытаются сформулировать советы по написанию чистого кода [1, 2, 3, 4, 5], которые зависят от используемого языка программирования, но во многом сходятся.

Эта статья изначально планировалась как своеобразная критика книги “Чистый код. Создание, анализ и рефакторинг” Роберта Мартина [1], поэтому я часто буду на него ссылаться. Мартин писал наиболее общие советы безотносительно конкретного языка программирования – этим его книга в корне отличается от других [2, 3, 4].

Статья не является сборником готовых инструкций к написанию кода, но должна наводить на мысль о том, как делать это более правильно.

Эволюция требований к чистому коду

Требования к коду менялись со временем. Очевидно, что в 80х годах компьютеры были менее производительны чем сейчас и огромный упор делался на эффективность программ. Рост производительности привел к появлению новых синтаксических конструкций, подходов к программированию и языкам. Так например, использование кодов ошибок вместо исключений в настоящее время считается дурным тоном, однако на заре компьютерной эры исключений просто не существовало.

Однако, изменение требований связано не только с ростом производительности – например, ограничение на ширину и высоту кода стали неактуальны с распространением мониторов с высоким разрешением. На старых мониторах строки, длина которых была более 80 символов, приходилось перематывать – это сильно осложняло чтение кода. Помимо ограничения на ширину, существовало также ограничение высоты функций – очень удобно если функция целиком умещается на один экран монитора. Сейчас эти требования не исчезли совсем, но стали более мягкими – писать весь код в одну строку не стоит.

Выработаны архитектурные конструкции, правильное использование которых упрощает проектирование, восприятие и сопровождение программ – шаблоны проектирования. Шаблоны имеют широкое распространение и хорошо описаны в литературе – если программист, читая исходный код увидит слово Factory, то он заранее знает чего ждать от такого кода. Для каждого шаблона проанализированы сильные и слабые стороны, поэтому их использование предпочтительнее велосипедостроения.

Наконец, изменились средства разработки программ – появились системы контроля версий, удобные инструменты тестирования, системы отслеживания ошибок, управления задачами и многое другое. Весь этот инструментарий оказался интегрирован в удобные среды разработки.

Независимо от того, какой язык программирования вы используете, хороший код должен обладать следующими характеристиками:

  • не должен мешать программисту вносить изменения;
  • должен легко тестироваться;
  • должны использоваться, по возможности, стандартные решения.

Соглашения о кодировании

В каждой конторе существуют свои собственные соглашения о стиле кодирования (coding conventions). Когда я устроился на свою первую работу – мне тоже выдали такой документ, который представлял собой сборник правил. Было не понятно чем обусловлены эти правила, но в будущем я узнал, что основная их часть имеет под собой крепкое основание.

Например в соглашении было регламентировано именование файлов с исходным кодом, которое, среди прочего, запрещало использование строчных букв. Правило может выглядеть причудливо, де тех пор, пока его нарушение не приведет к тому, что код будет отлично работать в Windows, но откажется собираться в Linux. Связано это с тем, что по умолчанию Linux учитывает регистр в именах файлов, а Windows – нет.

В соглашении обычно фиксируется использование множества специфичных для конкретного языка программирования конструкций. Например, для языка С++ может быть закреплено обязательное использование ключевого слова const везде где это возможно (это позволяет переносить обнаружение ряда ошибок на этап компиляции), запрет использования директив pragma (они могут оказать негативное влияние на переносимость программ) или, например, требование использовать, по возможности, const вместо define.

Отступы

Большое внимание в соглашениях уделяется расстановке скобок, пробелов и переводов строк и т.п.. Казалось бы, нет разницы – поставлен пробел перед фигурной скобкой или нет, однако все эти правила стремятся обеспечить:

  • Единый стиль оформления кода во всем проекте;
  • Визуальное выделение наиболее значимых частей.

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

В качестве примера я взял первую попавшуюся студенческую поделку – решаемая задача стоит в том, чтобы заполнить массив случайными числами, а затем обработать его элементы по заданной формуле:

int main()
{
  const double  a = 1, b = 2, c = 3;
  double s = 0;
  double y = 0;
  double x[40];
  for(int i = 0; i < 40; i++)
    {
      s = double( rand() % 1000);
      x[i]=(s / 300);
    }
  for(int i = 0; i < 40; i++)
  {
      y = a * pow(M_E, (b * x[i] + c * (x[i] * x[i]) )) ;
     cout << "For x[" <<  i  << "]," << "y[" << x[i] << "] = " << y << endl;
  }
}

Четвертая строка смещена вправо – возможно автор сделал это намеренно, чтобы нас о чем-то предупредить, но скорее всего, смещение произошло из за того, что при форматировании вперемешку использовались пробелы и символы табуляции. Современные среды разработки программ позволяют настроить автоматическую замену табуляций пробелами для решения указанной проблемы. Аналогичная проблема наблюдается в 15 строке.

Смещение тела цикла (7-11 строки) произошло, вероятно, в следствии модификации кода – изначально это был вложенный цикл, но затем студент что-то исправил, но форматирование сохранил. В маленькой функции такое отсутствие форматирования не сильно мешает, но в более серьезном коде, оно отвлекает, расходует ваше время и портит зрение. В конце концов, многие IDE имеют горячие клавиши, для форматирования фрагмента кода по заранее заданным правилам – достаточно один раз настроить среду разработки чтобы всегда экономить время.

В приведенном коде есть множество других недочетов:

  • в 9 строке выполняется приведение типа в функциональном стиле (тип используется как функция) и после открывающей скобки стоит пробел, но в 14 строке – при вызове функции pow, пробел не поставлен. Возможно, автор лишний пробел поставил умышленно и человек, читающий код, обратит на это внимание;
  • лишний пробел стоит перед объявлением переменных в третьей строке;
  • оператор присваивания в 9 строке выделен пробелами, но в 10 – пробелы отсутствуют.
  • Возможно, часть проблем связана с тем, что студент попросил помощи у одногруппников, которые исповедуют другие стандарты кодирования.

    В приведенной программе стоит множество лишних круглых скобок, которые очень сильно осложняют восприятие. Мало того, что скобки очень важны и часто таят в себе ошибки, они имеют свойство скапливаться – как в 14 строке. Большинство сред разработки подсвечивают парные скобки, но это не очень сильно облегчает жизнь.

    Общее правило состоит в том, чтобы не ставить скобки там, где они не нужны, при этом надо учитывать, что иногда лишние скобки надо оставить, т.к. далеко не все помнят в совершенстве приоритеты операций. В ряде случаев приоритеты можно показать пробелами (см. ниже).

    int main()
    {
      const double a = 1, b = 2, c = 3;
      double s = 0;
      double y = 0;
      double x[40];
    
      for(int i = 0; i &lt; 40; i++)
      {
        s = double(rand() % 1000);
        x[i] = s / 300;
      }
    
      for(int i = 0; i &lt; 40; i++)
      {
        y = a * pow(M_E, b*x[i] + c*x[i]*x[i]);
        cout << "For x[" <<  i  << "]," << "y[" << x[i] << "] = " << y << endl;
      }
    }
    

    В 16 строке вокруг оператора умножения нет пробелов, но вокруг сложения они поставлены. Такой прием позволяет визуально выделить приоритеты операторов, а в ряде случаев – избежать расстановки круглых скобок.

    Используя вертикальное форматирование, мы выделяем объявление переменных, цикл заполнения массива случайными числами и цикл обработки по формуле. Если ваша функция выполняет несколько действий – то разумно разделить соответствующие блоки кода пустыми строками.

    Приведенная программа все еще далека от совершенства. Возможно, открывающие фигурные скобки не стоило выносить на отдельную строку, а между ключевым словом for и открывающей круглой скобкой нужно поставить пробел. Такие вопросы связаны с конкретным языком программирования и являются скорее религиозными, чем техническими – поэтому я не уделю им внимания. Однако, нельзя не заметить “плохие” имена переменных.

    Имена

    Коротко и ясно ключевое правило именования сформулировал Мартин – “имя должно отражать намерения программиста“, большинство других советов вытекает из этого утверждения: имя не должно дезинформировать, содержать лишнее, отвлекать, …. Достаточно часто пишут про недопустимость каламбуров и шуток в именах, а в моей педагогической деятельности был случай:

    Студентка решала задачу о вычислении суммы ряда, при этом накопитель суммы назвала “i”, а счетчики циклов – “s” и “o”. На вопрос о том, почему она так назвала переменные, она ответила, что все ее одногруппники называют счетчики “i”, а сумму – “s” или “sum” – поэтому это серые, унылые имена, а ей хочется писать красивые программы с гламурными именами.

    Имена “i”, “j” зарезервированы для счетчиков, от них не ожидают другого поведения. Имя “s” логично использовать для накопления суммы, а имя “o” – вообще лучше не использовать (визуально оно плохо отличимо от ноля).

    Одно время мне приходилось использовать WinAPI, изобилующее всевозможными префиксами – разработчики Windows использовали Венгерскую нотацию, согласной которой тип своеобразным образом кодируется в имени [6].

    BOOL AdjustWindowRect(
      LPRECT lpRect,
      DWORD dwStyle,
      BOOL bMenu
    );
    

    В приведенном примере имена аргументов содержат закодированную информацию о типе. Так, префикс lp означает long pointer, префикс dwdouble word (два машинных слова – unsigned long), а префикс b кодирует логический тип данных.

    В настоящее время Венгерская нотация не в моде, причиной тому стала эволюция средств разработки. Сейчас программисту достаточно написать имя функции, чтобы IDE подсказала типы аргументов, при наведении указателя мыши (или каретки) на переменную может высвечиваться ее тип. С другой стороны, использование Венгерской нотации – это очень утомительно, мало того, что надо помнить все префиксы и печатать кучу лишних букв, так еще феерические проблемы подстерегают при изменении типа переменной.

    Тем не менее, частично такие нотации до сих пор применяются – например, я нахожу удобным дополнять имя областью видимости. Соглашение о стиле кодирования Google [7] предлагает в конце имени данных-членов класса ставить символ подчеркивания. Согласно правилам кодирования mozilla [8] различные префиксы присваиваются данным-членам, глобальным переменным, аргументам функций, статическим членам и константам.

    Мартин считает что и такие префиксы не нужны, его мнение разделяют многие программисты – на habrahabr не однократно проводились опросы о соглашениях кодирования и префиксах [9], которые это подтверждают. Например, вместо префикса, выделяющего данные-члены класса (часто это m, m_ или символ подчеркивания), предлагается использовать указатель на текущий объект – this (это не пройдет в списке инициализации конструктора):

    int SimpleClass::get() const { return this-&gt;val; }
    // вместо:
    // int SimpleClass::get() const { return m_val; }
    

    Кроме префиксов областей видимости есть и другие, например:

    • имена абстрактных классов (интерфейсов) дополняются префиксом I (ISocket), напротив – классы реализации могут снабжаться постфиксом Imp (SocketImp) или Impl (при использовании идиомы Pimpl). Класс в составе иерархии может содержать префикс C (CFigure), а классы исключений – постфикс Exception (BadArgumentsException)[1, 2, 10]. Есть множество других вариантов, которые часто противоречат друг другу.
    • имена функций дополняются префиксами:
      • is_ – проверяет что-то и возвращает логический тип – is_digit;
      • has_ – выполняет поиск какого-либо значения в контейнере – has_primeNumber;
      • get_ и set_ – метод возвращает или устанавливает значение какого-либо поля – set_volume, set_volume;
    • используются схемы именования, позволяющие различать объекты и типы данных – имена пользовательских типов предлагают начинать с заглавной буквы, а имена объектов – со строчной.

    Правила именования не ограничиваются префиксами, например:

    • названия должны использовать по возможности слова из предметной области решаемой задачи;
    • имена классов должны выражаться существительными, функций и методов – глаголами;
    • имена классов должны быть хорошо различимы – Страуструп приводит пример с именами fl, f1, fI и fi [11].

    Важно соблюдение одних и тех же правила всеми разработчиками проекта, в противном случае проблем не избежать. Например, один программист может захотеть писать имена всех констант заглавными буквами, а другой – выводить заглавными только макросы, в то время, как константы будет выделять заглавной буквой в начале и “верблюжьим регистром“.

    // pr1.h
    #define PI 3.14f
    enum Digits { ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE };
    const int STANDARD_ATMOSPHERIC_PRESSURE = 101325;
    
    // pr2.h
    const float TripleWaterPointTemp = 273.16f;
    
    // pr.cpp
    #include "pr1.h"
    #include "pr2.h"
    

    Приведен утрированный пример, однако, в файле pr.cpp окажутся как константы, объявленные первым программистом, так и вторым. Различия в обозначениях будут мешать обоим программистам – один может думать, что FIVE – это макрос, другой не сразу поймет, что TripleWaterPointTemp является константой.

    Комментарии

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

    • о версии кода и, внесенных в ней, изменениях;
    • об авторе кода или конкретных правок,
    • о лицензии, по которой распространяется код;
    • о неисправленных ошибках и прочих недочетах, заметки разного рода.

    От комментариев, несущих информацию об авторском праве и лицензии никуда не деться, однако с остальными можно бороться – в последнее время все шире распространяется мнение, о том, что “комментарии – признак плохого кода” [12, 13]. Впрочем, есть и другое мнение – так, например, соглашение о кодировании mozilla требует использовать комментарии в стиле JavaDoc [8], а Мейерс в одном из своих 55 советов упоминает doxygen [2].

    Существуют разногласия, однако, все программисты сходятся на том, что:

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

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

    • информацию о версии программы, авторе изменений и ее особенностях позволяют хранить системы управления версиями [14 , 15];
    • комментарии TODO, BUG и FIXME могут быть перенесены в трекеры задач и ошибок.

    В информации, связанной с описанием ошибки или версии программы обычно указывается дата время и автор изменений – специализированные системы делают это автоматически в едином формате. Кроме того, такие системы управляют доступом к задачам (могут как сделать информацию общедоступной, так и доступной узкому кругу лиц) и позволяют распределять задачи и изменять их статус. Очевидно, что использование специализированных инструментов предпочтительнее.

    Несмотря на то, что современные среды разработки умеют обрабатывать и выводить в окошках информацию о TODO, FIXME, NOTE и прочих специальных комментариях, могут существовать различия в формате:

    //TODO: сделать дело
    // TODO: гулять смело
    

    Различные IDE могут как среагировать на оба комментария, так и ни на один из них :). В данном случае проблему создал один лишний пробел – в конторе где я работал с этим столкнулись, когда начали переносить проект с Windows (использовали Microsoft Visual Studio) на Linux (в качестве IDE выбрали Qt Creator).

    Комментарии часто дублируют код – когда код понятен без комментариев. Особенно хорошо это видно при написании комментариев для doxygen или javadoc. Системы типа doxygen позволяют строить документацию к программе по исходному коду, при этом сама документация размазывается по коду в виде комментариев, записанных в специальном формате [16, 17]. Использования этих систем требуют многие соглашения о кодировании, использовались они и в фирме где я работал.

     /**
    * A pure virtual member.
    * @see testMe()
    * @param c1 the first argument.
    * @param c2 the second argument.
    */
    virtual void testMeToo(char c1,char c2) = 0;
    

    В приведенном фрагменте – “pure virtual member” заменяет описание функции, обычно на этом месте пишут что именно делает функция. Кроме того, часто пишут и короткое, и полное описание (они по-разному отображаются в документации). Тег “@see” позволяет связывать функции (связи отображаются в документации) – есть другие типы связей, а еще якоря, ссылки, секции, параграфы и т.п. Теги @param используются для описания аргументов функции.

    Пример взят без изменения в официальной документации и ярко демонстрирует недостатки комментариев doxygen. Вообще, комментарии в этом случае нужны лишь потому, что у функции и аргументов выбраны плохие имена. С другой стороны, если имена были бы выбраны правильно, то комментарии попросту бы их дублировали. Дополнительные пометки – такие как теги, секции и т.п. – быстро устаревают. Программист может изменить тело функции (находящееся в другом файле), а неактуальными окажутся пометки в файле описания функции.

    В реальных программах недостатки таких комментариев еще более очевидны, т.к. в них нет непонятного “pure virtual member”, а каждая функция решает вполне определенную проблему. Код, приведенный ниже, взят из статьи про разработку игры. Дописанные комментарии ничего по существу добавить не могут, однако значительно увеличивают размер исходного кода – очевидно, что на их написание и поддержку расходуется немало времени.

    //! игровой экран является виджетом
    class GameScreen : public QWidget {
      Q_OBJECT
    public:
      //!&lt; конструктор
      explicit GameScreen(QWidget *parent = 0);
      //!&lt; деструктор
      virtual ~GameScreen();
    public slots:
      //!&lt; перезагрузка
      void reload();
      /**
      * загрузка игрового экрана
      * @param nset номер сета.
      * @param nlevel номер уровня.
      * @param width ширина уровня.
      * @param height высота уровня.
      * @param leveldata данные, используемые для загрузки уровня.
      */
      void load(int nset, int nlevel, int width, int heigth, QString leveldata);
    private slots:
      /**
      * слот обработки сигнала завершения игры
      * @param gameResult результат игры.
      */
      void on_finished(bool gameResult);
    

    Поддерживать соответствие кода и документации тяжело в любом случае – при изменении функции надо изменять документацию. Системы типа doxygen смешивают документацию с кодом, но никак не решают проблему.

    С другой стороны, чтобы использовать doxygen, совсем не обязательно писать дополнительные комментарии. Если в вашей программе используются нормальные имена, то и документация получится съедобной – система doxygen построит вам нужные диаграммы (не только такую, как приведена ниже) и упакует все в удобный для чтения формат:

    doxygen_class_diagram

    диаграмма классов doxygen

    Выводы этой статьи состоят в том, что:

    1. форматировать код надо. Единообразно;
    2. правильные имена переменных могут сильно помочь при поддержке проекта;
    3. комментарии не решают проблемы плохого кода;
    4. современные инструменты разработки могут значительно облегчить поддержку и улучшить код;
    5. не всем советам “чистого кода” надо слепо следовать – часть из них может навредить.

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

    Список литературы:

    1. Мартин Р. Чистый код. Создание, анализ и рефакторинг. Библиотека программиста. – СПб.: Питер, 2014. – 464 с.
    2. Мейерс. С. Эффективное использование C++. 55 верных советов улучшить структуру и код ваших программ – М.: ДМК Пресс, 2006. – 300 с.
    3. Мейерс. С. Наиболее эффективное использование С++. 35 новых рекомендаций по улучшению ваших программ и проектов. – М.: ДМК Пресс. – 294 с.
    4. Саттер Г. Решение сложных задач на С++ (серия C++ in Depth). – М.: Издательский дом “Вильямс”, 2003.-400 с.
    5. Вогел Д. Шесть советов по написанию более понятного программного кода [Электронный ресурс].режим доступа: http://www.ibm.com/developerworks/ru/library/l-clear-code/. Дата обращения: 09.10.2014.
    6. Microsoft. MSDN: Coding Style Conventions [Электронный ресурс]. режим доступа: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378932%28v=vs.85%29.aspx. Дата обращения: 09.10.2014.
    7. Google C++ Style Guide [Электронный ресурс]. режим доступа: https://google.github.io/styleguide/cppguide.html. Дата обращения: 09.10.2014.
    8. Mozilla. MDN Coding Style [Электронный ресурс]. режим доступа: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style. Дата обращения: 09.10.2014.
    9. Habrahabr: Используете ли вы префиксы в именах членов классов? [Электронный ресурс]. режим доступа: http://habrahabr.ru/post/124417/. Дата обращения: 09.10.2014.
    10. Microsoft. MSDN: Имена классов, структур и интерфейсов [Электронный ресурс]. режим доступа: http://msdn.microsoft.com/ru-ru/library/vstudio/ms229040%28v=vs.100%29.aspx. Дата обращения: 09.10.2014.
    11. Stroustrup B. Bjarne Stroustrup’s C++ Style and Technique FAQ [Электронный ресурс]. режим доступа: http://www.stroustrup.com/bs_faq2.html. Дата обращения: 09.10.2014.
    12. Habrahabr: Не пишите комментарии к коду! [Электронный ресурс]. режим доступа: http://habrahabr.ru/post/178653/. Дата обращения: 09.10.2014.
    13. Habrahabr: Почему [не]нужно комментировать код [Электронный ресурс]. режим доступа: http://habrahabr.ru/post/207390/. Дата обращения: 09.10.2014.
    14. IBM: Управление исходным кодом с помощью Git [Электронный ресурс]. режим доступа: http://www.ibm.com/developerworks/ru/library/l-git/. Дата обращения: 09.10.2014.
    15. Чакон Скотт, Страуб Бен Git для профессионального программиста. — СПб.: Питер, 2016. — 496 с.: ил.
    16. Васильев В. Игра “Сапер”. Паттерн Mediator. Использование doxygen [Электронный ресурс]. режим доступа: https://pro-prof.com/archives/887. Дата обращения: 09.10.2014.
    17. Doxygen: documentation [Электронный ресурс]. режим доступа: http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html. Дата обращения: 09.10.2014.

7 thoughts on “Теория чистого кода. Стиль кодирования

  1. Лилия

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

    Reply
  2. Андрей

    А что в статье является критикой Мартина? Кажется, он про все это пишет.

    Reply
    1. admin Post author

      В статье написано, что она “изначально планировалась как критика”, но критика – это не интересно, поэтому я собрал кучу всяких авторитетных источников (типа соглашений google, mozilla, книг Мейерса и других публикаций) и посмотрел на них сквозь советы Мартина. Очевидно, что если советы других авторитетных людей не соответствуют тому, что пишет Мартин – то все не так гладко. Больше всего Мартина, наверное критикует вывод о том, что не надо слепо следовать всяким советам и соотносить сложность соблюдения этих правил с извлекаемой выгодой.

      Я писал же все на основе своего опыта, поэтому, скажем, о doxygen иного мнения не было (я реально не понимаю зачем mozilla требует писать для него комментарии, но пока Мартин не переубедил меня – я тоже писал их….). По префиксам и другим схемам кодирования критика присутствует (все очень не однозначно). Кстати, в примерах книги Мартин сам использует такие схемы – ведь стабильно имена переменных начинает со строчной буквы, а типов – с заглавной…

      Кстати, еще эпичный пример – Вогел [5] предлагает использовать макрос define как можно чаще, но множество программистов с этим не согласны :). Я думаю, лучшей критикой в этом случае будет ссылка на совет, например, Мейерса [2]. С Мартином аналогично.

      Reply
  3. Андрей Валяев

    Что касается венгерской нотации – в WINAPI эту идею в достаточной степени извратили. Дублирование в переменной информации о типе – это всетаки дублирование. И никому не охота в случае изменений все синхронизировать. 🙂

    Спольски рассказывал в своем блоге о том, что в команде MS Word венгерскую нотацию использовали совсем по другому. Для хранения класса переменной. К примеру x – имеет отношение к ширине. y к высоте. В одном выражении встретить x и y – странно… Но это не имеет отношения к типу.

    Reply
  4. Стрелец

    Относительно комментариев. По моему мнению, должна быть “золотая середина”.
    С одной стороны избыточное комментирование не оправдывает себя, но, с другой стороны, недостаточное комментирование либо его полное отсутствие тоже “не есть хорошо”. Особенно, если речь идёт о реализации сложных алгоритмов, а также крупных и/или продолжительных проектах.
    Комментарии должны быть, но только там, где они действительно необходимы.
    По поводу Венгерской нотации:
    Как минимум, многие современные IDE уже “из коробки” имеют достаточно мощный функционал для облегчения работы с кодом. Поэтому, в частности, нет необходимости перелистывать море кода, для того чтобы поменять названия переменной, свойства, метода и т.д.
    А, вообще добавлять в переменную имя типа, в подавляющем большинстве случаев, действительно излишество. Если вспомнить Линуса Торвальдса: ” компилятор и так знает типы и может проверить их”.

    Reply
  5. Андрей

    замудрено написано. То, что код править нужно, сомнений нету, но лучше уж и писать его сразу правильно

    Reply
    1. admin Post author

      Сразу правильно писать код невозможно (если речь идет не о форматировании и прочих мелочах), потому что код не мертвый, он изменяется. Мы можем сегодня что-то написать, завтра добавить новый функционал, из-за которого часть старого кода станет ненужной. На помощь приходит рефаторинг, по которому целые книги написаны, например у Фаулера (это не только перенос кода, удаление ненужного кода и прочие мелочи, но и способы устранения нарушения SOLID-принципов, например – а это очень важно чтобы проект не загнулся быстро).

      Особенно это касается комментариев – они устаревают первыми, поэтому в конце статьи описаны 2 разных подхода – использование систем типа javadoc/doxygen/… или вообще отказ от использования комментариев. Последний вариант оказывается непопулярным в некоторых кругах программистов (особенно старой школы), однако он однозначно набирает популярность благодаря простоте, эффективности и хорошим современным книжкам.

      В статье описаны в основном вещи, связанные со стилем кодирования, т.е. именованием, отступами и прочей ерундой, однако это тоже важно и не всегда возможно писать это “сразу правильно” – например, если мы не пишем код сами, а получаем его в наследство от других разработчиков (или как часто бывает – от другой группы разработчиков из вашей фирмы, но находящихся в другом филиале).

      Вообще, когда я прочитал ряд книжек по рафакторингу – мое отношение к коду сильно изменилось (я вообще делю свою профессиональную деятельность на ДО и ПОСЛЕ этого момента). До этого я не понимал зачем тимлид усложняет нам жизнь какими то бредовыми соглашениями (и они реально были такими, т.к. сам тимлид не понимал для чего они нужны). Когда я прочитал книжки я понял одну простую вещь – соглашения призваны упростить будущую разработку, а поэтому ни в коем случае не должны ничего усложнять, ну а еще я набрался терминов и веских аргументов чтобы парировать тимлиду (хотя с тех пор я уже 3 работы сменил, но это всегда пригождалось). Ну вот возьмите например соглашения об именование юнит-тестов (таких же функций, как и все остальные) – можно усложнить их бесконечно, но если посмотреть книжки – то найдем лишь два базовых правила – одна проверка на тест; имя теста должно отражать суть тестового случая. Зачем все это нужно будет понятно либо когда шишек набьешь сам, либо когда прочитаешь веские аргументы.

      Кстати, по теме рефакторинга (и особенно чистого кода) написано зашкаливающее количество статей. Очень часто они действительности не соответствуют – всегда надо смотреть кто их пишет и когда. Очень часто их пишут более чем некомпетентные люди, но бывает, что информация просто устаревает – так я на MSDN находил 2 статьи очень авторитетных авторов, но утверждающих прямо противоположное. Это может быть связано как с разными подходами (например, как я выше описывал в отношении комментариев), так и с устаревшей информацией – например когда-то использование макросов типа #define в С++ было нормой и многие рекомендовали их применять, однако сейчас Маерс, Александреску и Страуструп написали сотни книг и статей об обратном.

      Reply

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вы не робот? *