10 принципов самодокументируемого кода

Привет! Сегодня я хочу поделиться советами по написанию совершенного понятного кода, взятые из книги Питера Гудлифа «Ремесло программиста // Практика написания хорошего кода».

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

1. Пишите простой код с хорошим форматированием


Формат представления оказывает огромное влияние на легкость понимания кода. Разумное представление передает структуру кода: функции, циклы и условные операторы становятся понятнее.

int fibonacci(int position)
{
     if (position < 2)
     {
         return 1;
     }
     int previousButOne = 1;
     int previous = 1;
     int answer = 2;

     for (int n = 2; n < position; ++n)
     {
         previousButOne = previous;
         previous = answer;
         answer = previous + previousButOne;
     }
     return answer;
}

  • Cтремитесь к тому, чтобы ход нормального выполнения вашего кода был очевиден. Обработка ошибок не должна отвлекать от нормальной последовательности выполнения. Условные конструкции if-then-else должны иметь единообразный порядок ветвей (например, всегда помещайте ветвь «обычного» кода перед ветвью «обработки ошибок», или наоборот).
  • Избегайте большого количества уровней вложенных операторов. В противном случае код становится сложным и требует пространных пояснений. Принято считать, что у каждой функции должна быть только одна точка выхода; это известно, как код Single Entry, Single Exit (SESE, один вход – один выход). Но обычно это ограничение затрудняет чтение кода и увеличивает количество уровней вложенности. Мне больше нравится приведенный выше вариант функции fibonacci, чем следующий вариант в стиле SESE:

    int fibonacci(int position)
    {
         int answer = 1;
         if (position >= 2)
         {
             int previousButOne = 1;
             int previous = 1;
    
             for (int n = 2; n < position; ++n)
             {
                 previousButOne = previous;
                 previous = answer;
                 answer = previous + previousButOne;
             }
         }
         return answer;
    }
    

    Я бы отказался от такой излишней вложенности в пользу дополнительного оператора return – читать функцию стало гораздо труднее. Весьма сомнительна целесообразность прятать return где-то в глубине функции, зато простые сокращенные вычисления в ее начале очень облегчают чтение.
  • Остерегайтесь оптимизации кода, в результате которой теряется ясность базового алгоритма. Оптимизируйте код только тогда, когда становится ясным, что он мешает приемлемой работе программы. При оптимизации сделайте четкие комментарии относительно функционирования данного участка кода.

2. Выбирайте осмысленные имена


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

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

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

3. Разбивайте код на самостоятельные функции


То, как вы разобьете код на функции и какие имена им дадите, может сделать код понятным или совершенно непостижимым.

  • Одна функция, одно действие

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

4. Выбирайте содержательные имена типов


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

  • Определяя величину, которая не будет меняться, назначьте для нее тип константа (используйте const в C).
  • Если переменная не должна принимать отрицательных значений, воспользуйтесь беззнаковым типом (при наличии его в языке).
  • Пользуйтесь перечислениями для описания связанного набора данных.
  • Правильно выбирайте тип переменных. В C/C++ записывайте размер в переменные типа size_t, а результаты арифметических операций с указателями – в переменные типа ptrdiff_t.

5. Применяйте именованные константы


Код типа if (counter == 76) вызывает недоумение. Каково волшебное значение числа 76? В чем смысл этой проверки? Практика волшебных чисел порочна. Они затеняют смысл кода. Гораздо лучше написать так:

const size_t bananas_per_cake = 76;
...
if (count == bananas_per_cake)
{
    // испечь банановый пирог
}

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

Это относится не только к числам, но и к строкам-константам. Присмотритесь к любым литералам, имеющимся в вашем коде, особенно если они встречаются многократно. Не лучше ли использовать вместо них именованные константы?

6. Выделяйте важные фрагменты кода


Старайтесь выделить важный код на фоне обычного материала. В нужном месте следует привлечь внимание читателя. Для этого есть ряд приемов. Например:

  • Разумно располагайте объявления в классе. Сначала должна идти информация об открытых объектах, поскольку именно она нужна пользователю класса. Закрытые детали реализации следует располагать в конце, поскольку они менее интересны большинству читателей.
  • По возможности скройте всю несущественную информацию. Не оставляйте ненужного мусора в глобальном пространстве имен. В C++ есть идиома pimpl, позволяющая скрыть детали реализации класса. (Meyers 97).
  • Не прячьте важный код. Не пишите в строке больше одного оператора и сделайте этот оператор простым. Язык позволяет писать очень изобретательные операторы цикла for, в которых вся логика укладывается в одной строке с помощью множества запятых, но такие операторы трудно читать. Избегайте их.
  • Ограничьте глубину вложенности условных операторов. В противном случае за нагромождением if и скобок трудно заметить обработку действительно важных случаев.

7. Объединяйте взаимосвязанные данные


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

По возможности объединяйте объекты с помощью языковых конструкций. В C++ и C# можно объединять элементы внутри одного пространства имен. В Java средством объединения служит механизм пакетов. Связанные друг с другом константы можно определить в перечислении.

8. Снабжайте файлы заголовками


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

/*********************************************************
* File: Foo.java
* Purpose: Foo class implementation
* Notice: (c) 1066 Foo industries. All rights reserved.
********************************************************/

9. Правильно обрабатывайте ошибки


Помещайте обработку всех ошибок в наиболее подходящий контекст. Если возникает проблема чтения/записи диска, ее нужно обрабатывать в том коде, который занимается доступом к диску. Для обработки этой ошибки может потребоваться сгенерировать другую ошибку (типа исключительной ситуации «не могу загрузить файл»), передав ее на более высокий уровень. Это означает, что на каждом уровне программы ошибка должна быть точным описанием проблемы в его контексте. Нет смысла обрабатывать ошибку, связанную со сбоем диска, в коде интерфейса пользователя.

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

10. Пишите осмысленные комментарии


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

Сначала попробуйте воспользоваться другими приемами. Например, проверьте, нельзя ли сделать код понятнее, изменив имя или создав вспомогательную функцию, и таким образом избежать комментирования.



Уверен, что уже после внедрения в привычку нескольких этих принципов вы сделаете на одного программиста счастливее. И этим счастливым программистом будете вы. Когда? В момент возвращения к работе над своим кодом полугодовой давности.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 134

    –19
    Пользуясь случаем, жутко бесит вот такое растянутое форматирование
    int fibonacci(int position)
    {
         if (position < 2)
         {
             return 1;
         }
         int previousButOne = 1;
         int previous = 1;
         int answer = 2;
    
         for (int n = 2; n < position; ++n)
         {
             previousButOne = previous;
             previous = answer;
             answer = previous + previousButOne;
         }
         return answer;
    }

    Если платят за строку кода — норм конечно, но все же нам лично всегда удобнее компактный код, когда можно больше обозреть на одном экране
    int fibonacci(int position) {
         if (position < 2) return 1;
         int previousButOne = 1, previous = 1, answer = 2;
         for (int n = 2; n < position; ++n)  {
             previousButOne = previous;
             previous = answer;
             answer = previous + previousButOne;
         }
         return answer;
    }

    Компактный код по сути так же очевиден, а т.к. перед глазами находится больше кода сразу, то не приходится мотать туда сюда для понимания большого участка.
    p.s.: Ох сейчас огребем снова:) Постоянный холивар на эту тему с коллегами.
      +25
      А тут на вкус и цвет фломастеры разные просто. Мне больше растянутый вариант удобен, он не сливается в сплошную простыню текста. Да и функций размером с целый экран стараюсь не писать, так что все видно, правда это в эмбеде, хз что там в большом софте у вас.
        +26
        Первый вариант более читаемый
          +25
          Ваш вариант с запихиванием как можно большего количество значений в одну строку — ничуть не лучше.
          Код должен легко читаться простым беглым взглядом. Ваш требует внимательно его просматривать, чтобы не пропустить что-то.
            +2
            «С коллегами» давно следовало бы выработать общий стиль, которого обязаны придерживаться все (и прекратить спорить по этому поводу). И для разных языков есть более-менее общепринятые стандарты оформления кода, для PHP, например, это PSR. И да, мне там некоторые вещи не нравятся, но я его придерживаюсь ибо стандарт.
              +3

              Для всех, кроме С++)) Я прямо сейчас могу назвать пяток "общепринятых" стилей, которые отличаются друг от друга почти перпендикулярно :D

              +20

              ХЗ. У меня от вашего варианта глаза выпадают, потому что логика и данные слипаются в одну кучу. Логика отдельно, данные отдельно.


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


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


              В общем, на мой взгляд, ваш вариант — это прямо квинтэссенция того, как писать не надо.

                0
                Со скобками хорошо помогают нормальные редакторы, читается такой код проще чем в блокноте.
                Тут ещё нюанс в блоке «Пишите короткие функции. В них легче разбираться.». Мне тоже больше нравится, когда { на отдельной строке, но например функция тогда не влезает на экран. Если же писать { в одну строку то размер визуально меньше, проще охватить взглядом. И ещё нюанс — если код линейный, но получается например на 10 экранов, мой опыт показал что делить на функции это только снижать читаемость. Есть точка входа, есть точка выхода, вызовы всего кода 1 раз (что не 1 — уже вынесено), но код вышел в 10 экранов. При этом он легко читается, легко отлаживается, а попытки разбить на подфункции только сломали читаемость и всё.
                  0
                  При этом он легко читается, легко отлаживается, а попытки разбить на подфункции только сломали читаемость и всё
                  Значит, не умеете бить на подфункции.
                    –3

                    Важная часть умения бить на подфункции — уметь не бить на подфункции

                    +1
                    Есть две ситуации — 1 человек говорит сомнительную вещь о том, что одно работает, другое нет
                    2. человек пишет код на 10 экранов и считает, что тот легко читаем.

                    Ответ один — напиши тест.
                  –7
                  Почему бы не взять «золотую середину»? Одна строка — одно действие:

                  int fibonacci(int position) {
                       if (position < 2) 
                            return 1;
                       int previousButOne = 1;
                       int previous = 1;
                       int answer = 2;
                       for (int n = 2; n < position; ++n)  {
                           previousButOne = previous;
                           previous = answer;
                           answer = previous + previousButOne;
                       }
                       return answer;
                  }
                  
                    +14
                    Это не золотая середина.
                    Например однострочные ifы — прямой путь к ошибкам из-за добавления новых строк с забыванием что там нет скобок.
                      0

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


                      Читаемый код имеет структуру, прибитую гвоздями в паскале:


                      1. Сначала информация о данных, над которыми работаем (типы и объекты)
                      2. Потом трансформация этих данных
                      3. Затем конвертация данных в тип возврата (если необходимо) и собственно возврат данных из функции.

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


                      Однако сама идея была гениальной и простой. Если в паскале эти блоки разделялись очень явно, то современных языках нужно просто добавить одну пустую строку и всё)


                      Всем, кто пишет вот такие слипшиеся сплошные куски кода, так и хочется прописать немного курсов Паскаля в резюме))


                      P.S.
                      Забавно, но пока что 100% встретившихся мне любителей такого стиля написания кода обычно почти не пишут код в IDE, а используют текстовые редакторы (vim, Atom, vscode, sublime, etc). Разрушьте кто-нибудь мою статистику :}

                        +2
                        Читаемый код имеет структуру, прибитую гвоздями в паскале:

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


                        А в некоторых языках функции больше 4-5 строк — уже немножко моветон.

                          0

                          Ну, это зависит. Например если нужно гарантированно какие-то ресурсы освобождать при выходе из любой точки функции, то вместо множественного return может даже множественный go to потребоваться, и это не антипаттерн ни разу, в том числе в приличных домах (см. Linux core style guide). Правда это больше про Си, но все же.

                            +1
                            Правда это больше про Си, но все же.

                            Вот именно. В современном C++ для таких вещей принято на RAII полагаться.
                            +1
                            Почему же только в C++? У нас в команде (C#) тоже действует правило: «Переменная должна объявляться максимально близко к месту первого использования». И множественные return приветствуются.
                              +1

                              Скорее должно быть C++-подобные (но не Cи!) — C#, Java, JS etc

                                0

                                Почему не Си?

                                  0
                                  А почему «но не С»?
                                    +2

                                    Потому что в Си не везде можно нормально использовать in-place конструирование для составных типов, как в случае с более продвинутыми языками. Каскады инициализаций, с переходами же к каскадам деинициализаций, ручное управление памятью играют не на руку — лучше иметь кучку указателей в одном месте, нежели разбросанных где-то в середине функции.
                                    То есть


                                    c-1
                                    void* someFunc() {
                                      struct A* a = NULL;
                                      struct B* b = NULL;
                                      if (init_a(a) < 0) {
                                        return NULL;
                                      }
                                      if (init_b(b)) {
                                        return NULL;
                                      }
                                       /// пару десятков строк функционала спустя
                                      void* ret = (void*)a->some(b);
                                      deinit_a(a);
                                      deinit_b(b);
                                      return ret;
                                    }

                                    на мой взгляд несколько удобнее чем


                                    c-2
                                    void* someFunc() {
                                      struct A* a = NULL;
                                      if (init_a(a) < 0) {
                                        return NULL;
                                      }
                                      struct B* b = NULL;
                                      if (init_b(b)) {
                                        return NULL;
                                      }
                                      /// пару десятков строк функционала спустя
                                      void* ret = (void*)a->some(b);
                                      deinit_a(a);
                                      deinit_b(b);
                                      return ret;
                                    }

                                    т.к. сразу видно потенциальное количество точек отказа. В С++ и прочих же таких проблем заметно меньше — тебе умные указатели, и конструкторы которые в памяти конструируют не отходя от стека, и области видимости логически чуть более инкапсулированны, и статические проверки, встроенные в язык.
                                    Например, если мне не изменяет память ипользование var в js объявляло переменную в глобальном скоупе, с приходом let и constони наконец стали локальными и чем ближе к использованию переменная, тем отказоустойчивей и выгоднее оно в плане использования памяти.
                                    Общий посыл примерно такой, но естественно есть нюансы и некоторые исключения из этих правил.

                                      –1
                                      Честно говоря, глядя на оба листинга, я принципиальной разницы между ними не вижу. Но вижу ошибку, из-за которой, видимо, в С некоторые используют goto и метки. У вас в случае неинициализации B не хватает деинициализации A перед выходом. И вот для исключения подобных ошибок часто используют отдельный блок деинициализации в конце функции с меткой, в который переходят при помощи goto в случае ошибки:
                                      пример
                                      void* someFunc() {
                                         // function body ...
                                      exitFunc:
                                         if (b != NULL) {
                                            deinit_b(b);
                                         }
                                         if (a != NULL) {
                                            deinit_a(a);
                                         }
                                         return ret;
                                      }
                                      



                                      При таком подходе вынос в начало определения всех переменных, которые нужно в конце деинициализировать, как раз имеет смысл. Но, все равно, это скорее как исключение. По умолчанию я бы определял переменные как можно ближе к месту использования даже в С. Но я давно не пишу на С, вполне могу что-то упускать.
                                        +1

                                        Вот хотел написать без goto, ан все равно потек в памяти. Собственно такие нюансы и делают его исключением среди прочих Си-подобных языков. IMHO

                                        0
                                        У вас в обоих случаях идет потеря памяти на return из второго if. В вашем примере лучше сделать гото на точку деинита. Как-то так:

                                        void* someFunc() {
                                          struct A* a = NULL;
                                          if (init_a(a) < 0) {
                                            return NULL;
                                          }
                                          void* ret = NULL;
                                          struct B* b = NULL;
                                          if (init_b(b)) {
                                            goto delA;
                                          }
                                          /// пару десятков строк функционала спустя
                                          ret = (void*)a->some(b);
                                          deinit_b(b);
                                        delA:  deinit_a(a);
                                          
                                          return ret;
                                        }
                                        
                                        
                                    0

                                    Ну, тем более. Я-то из всех си-подобных только на C++ пишу, поэтому только про него говорить могу.

                                +1

                                Не вижу ничего плохого в простых проверках вроде if (!can_go_next) return, по-моему очень даже читабельно, все что больше чем вызов одной функции / выход из функции — в скобки. Ну и на новую строку лучше не переносить, это да.

                                  +3
                                  Вот только беглый взгляд может не увидеть, что там return и решить что выполняемый код ифа идет строчкой ниже.
                                  Да, ошибка тупая. Но посмотрите на статьи о PVS — там 99% ошибок тупые.
                                    0
                                    решить что выполняемый код ифа идет строчкой ниже.

                                    Если есть такая возможность, ставится пустая строка.

                                    У того же MS в опернсоурсных библиотеках миллион мест типа

                                    public void SomeFunc(arg0, arg1)
                                    {
                                             if(arg0 == null) new ArgumentNullException(nameof(arg0));
                                             if(arg1 == null) new ArgumentNullException(nameof(arg1));
                                    
                                             DoSmthng(arg0, arg1);
                                    }
                                    


                                    Всё вполне компактно и читабельно.

                                      0

                                      Это какие-то autothrowable exceptions? Или throw потерялся?

                                    +4

                                    Миллион раз ловил себя на такой проблеме:


                                    1. Читаешь код где всегда if и ниже блок кода с веткой кода
                                    2. Попадается однострочный if
                                    3. Глаз автоматически смотрит на условие, а потом скользит вниз смотреть что там исполняется в этой ветке
                                    4. А там нихрена нет (в лучшем случае) или начинаешь читать код не относящийся вообще к этому if-у как ветку выпоняющуюся под условием этого if-а (что плохо совсем)
                                    5. Случается в мозгу cache miss, приходится взглядом возвращаться назад, вчитываться и в общем врубать другие операции, замедляющие беглый просмотр кода.
                                      +1
                                      Мы ориентируемся по отступам, поэтому такой вариант
                                      if(1) return;
                                      printf("...

                                      не вызывает вопроса относится ли принт к условию или нет, а заодно такой вариант
                                      if(1) {
                                         return;
                                      }

                                      не вызывает проблем увидеть начало условия и его конец (нет необходимости занимать строчку под фигурную скобку).
                                        0

                                        Аналогично. Имхо однострочный if-then при нормальном оформлении и без чрезмерной вложенности условия и действия читается даже проще.


                                        А вот к применению брекетов в стиле K&R я почему-то равнодушен. Мне тупо нравится, когда открывающий брекет стоит в отдельной строке.

                                        0

                                        А я не ставлю скобки вокруг ифов из одного стейтмента, и у меня ни разу за последние лет 10 точно не было описываемой вами проблемы. Видимо, восприятие разное.

                                          0
                                          А у коллег, которые работают с вашим кодом?
                                        +2
                                        Не вижу ничего плохого в простых проверках вроде if (!can_go_next) return, по-моему очень даже читабельно

                                        Как в таком варианте поставить брек-поинт на return?
                                          0
                                          Просто ставите курсор на ретурн и нажимаете «сделать брекпоинт».

                                          Если с этим какие-то проблемы(не представляю какие, ведь брекпоинт ставится не на строчку, а на «выражение», но допустим), то делаете conditional breakpoint.
                                      0

                                      Если следовать этому правилу то и объявление цикла надо разбивать на три строчки

                                      +4

                                      Я бы сделал вот так:


                                      int fibonacci(int position) {
                                           if (position < 2) return 1;
                                      
                                           int previousButOne = 1, previous = 1, answer = 2;
                                      
                                           for (int n = 2; n < position; ++n)  {
                                               previousButOne = previous;
                                               previous = answer;
                                               answer = previous + previousButOne;
                                           }
                                      
                                           return answer;
                                      }
                                        +1
                                        У Вас очень хороший вариант (тоже так пишем, когда логические блоки более важно отделять) демонстирующий еще одну важную вещь
                                        В «компактном» коде отступы пробельными строками между логическими блоками (объявление переменных, логика. возврат) сразу сходу заметны.
                                        В «воздушном» коде отступы пробельными строками заметны плохо или приходится их делать по две штуки.
                                          +1

                                          У меня java background, мне можно. Там принято фигурную скобку на той же строке открывать.


                                          В C++, имхо, лучше не бежать поперек паровоза и использовать принятый там (и командой) стиль кода. Классика же — холиварность вопроса прямо пропорциональна его незначительности.


                                          Взять меня — я был С++ разработчиком, ставил фигурные скобки с новой строки и обожал табы. При переходе на java пришлось подстроиться под команду и я от этого только выиграл. Например, на ревью было больше вопросов по делу и меньше по всякой фигне типа фигурных скобочек :-)

                                          • UFO just landed and posted this here
                                              +4

                                              Если речь о фигурных скобках в Java, то это пошло из Java Code Conventions от Sun, а сейчас похожих правил придерживаются ребята в Google и, скажем, разработчики Spring.


                                              Не стандарт, конечно, но иногда люди защищают традиции более воинственно чем какие-то там стандарты или законы.

                                          +2
                                          Придерживаюсь того же подхода.
                                          Но всё таки
                                          int previousButOne = 1;
                                          int previous = 1;
                                          int answer = 2;
                                            0
                                            Везде практикуем такой подход — облегчает понимание что поменялось на ревью, дает возможность оперативно что-то выкинуть и главное, облегчает понимание типа и избавляет от ошибок:
                                            char * aaa, bbb;
                                            

                                            Скажете не задумываясь тип bbb?
                                              0

                                              Чего тут думать. char.

                                                +1
                                                Не обманывайте, вы задумывались!
                                                При беглом просмотре многие и часто относят модификатор к типу, а не к переменной.
                                                  0
                                                  Ну если только на пару секунд.
                                                +1
                                                Привык писать однотипные (по типу и смыслу) переменные в одну строку:
                                                LPCTSTR pszFolder, pszFilename, pszExtension;

                                                Здесь не возникает проблемы с поинтерами, т.к. они уже вынесены в typedef.
                                                Но если возникает сомнения вида:
                                                const auto & var = G_Var, var2 = G_Var2; // avoid this definition

                                                То не полезу в книжку вспоминать, напишу каждую на отдельной строке.
                                                
                                                const auto & var = G_Var;
                                                const auto & var2 = G_Var2; // Thats good

                                            +1
                                            Главное, чтобы в рамках одного проекта все следовали единому стилю оформления кода. Когда глаза привыкнут, станет удобно. Что касается отступов возле конструкций типа if, они попадают под Стиль Олмана, он же Беркли, он же BSD, а потому является допустимым. Так что если автор статьи правит под свои задачи исходники FreeBSD, то он совершенно оправданно использует данный стиль, потому как он принят в BSD сообществе. Все остальное — вкусовщина.
                                              0
                                              Поддерживаю Ваш вариант.
                                              • UFO just landed and posted this here
                                                  –2
                                                  if (position < 2) return 1;

                                                  ТАК ВЕРСТАЮТ ТОЛЬКО МУДАКИ ©
                                                    0

                                                    сарказм_вкл
                                                    Если платят за строчки, буквы и лишние переменные — норм конечо, но можно уместить и гораздо больше кода на экране.


                                                    int fib(int pos) {
                                                        int a = 1;
                                                        for (int p = 1; pos > 1; --pos, a += p, p = a - p) ;
                                                        return a;
                                                    }

                                                    Не благодарите
                                                    сарказм_выкл

                                                      +1
                                                      js версия
                                                      ゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
                                                      0
                                                      а почему бы тогда инлайн до конца видимой строки не писать, так больше войдет на экран?
                                                        0
                                                        Поддерживаю.
                                                        –3

                                                        Хорошее логирование сильно упрощает понимание кода.

                                                          +4

                                                          Логгирование предназначено немного не для этого. Если о предназначении кода можно догадаться только по текстовым строкам логгирования, то у меня плохие новости о качестве вашего кода...


                                                          Логгирование не должно упрощать понимание кода, тем более сильно.

                                                          +7

                                                          11. Не стесняйтесь вставлять пустые строки, разделяя смысловые блоки в рамках одной функции
                                                          12. Над каждым публичным классом и каждой публичной функцией должен быть комментарий. Да, код самодокументируемый и всё такое, но для этого его надо прочитать и осознать
                                                          13. В сложных местах (особенно если у будущего читателя может появиться желание "упростить" код) должен быть комментарий, объясняющий, почему было сделано именно так
                                                          14. самодокументируемого кода не бывает, бывает документированный код и недокументированный код

                                                            +6
                                                            А еще бывает неверно документированный код: с устаревшими комментариями, с копипасченными комментариями. Очень помогает запутаться!
                                                              0
                                                              «Все врут» (с) доктор Хаус
                                                              Верить документации, комментариям и прочему нарративу нужно очень осторожно.
                                                              Не врет только код и отчасти тесты.
                                                              Код, потому что он делает, то что на нем написано. Тесты, если обложены ассертами, тоже не врут.
                                                              +2

                                                              Требование писать комментарий к каждому методу слишком категоричное.
                                                              Название метода должно объяснять, что делает метод.
                                                              А комментарий — как метод это делает. При этом комментарий нужен только, если реализация метода нетривиальна.
                                                              8 пункт с комментарием всего файла выглядит слабо. Я считаю, что 99% программистов будут ожидать, что в файле Foo.java будет реализация класса Foo. Поэтому заголовочные комментарии в большинстве случаев не обязательны.

                                                                +1

                                                                Вы неправильно понимаете назначение заголовочных комментариев. Как и в остальных комментариях, там должно быть не то, что уже написано в коде, а то, чего в коде, как минимум, явно, нет. Назначение класса (что вовсе не обязано совпадать с тем, что он делает), архитектурные ограничения, поддержка многопоточности, принятые в нем особенности работы с транзакциями и т.п.


                                                                В Java-мире учиться писать комментарии можно на примере JRE и spring-core

                                                              • UFO just landed and posted this here
                                                                  +1
                                                                  Документированного кода не бывает, бывает недокументированный и самодокументированный код.
                                                                    +2
                                                                    Вполне себе документированный код, не являющийся самодокументированным
                                                                    /* On some laptops (Sony, i'm looking at you) there appears to
                                                                    * be no direct way of accessing the panel's EDID.  The only
                                                                    * option available to us appears to be to ask ACPI for help..
                                                                    *
                                                                    * It's important this check's before trying straps, one of the
                                                                    * said manufacturer's laptops are configured in such a way
                                                                    * the nouveau decides an entry in the VBIOS FP mode table is
                                                                    * valid - it's not (rh#613284)
                                                                    */
                                                                    if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
                                                                    	if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
                                                                    		status = connector_status_connected;
                                                                    		goto out;
                                                                    	}
                                                                    }

                                                                      0
                                                                      Это пока.
                                                                      У программиста будет аврал при починке бага на проме, и он быстро поменяет код, даже не взглянув на комментарий — всё, ваша документация врёт.
                                                                      Не обязательно аврал: просто может быть невнимательный человек; конец десятичасового рабочего дня; просто пофигист и т.д.

                                                                      Проблема такой «документации» в том, что она человекозависима, а значит — ненадёжна, а значит — ей нельзя доверять и мало кто её будет читать, а значит — и писать её не стоит.

                                                                      Есть, конечно, исключения, когда комментарии писать нужно: если изменения в данном месте могут аукнуться совсем в другом (читатель кода может не знать этого) и если разработчик выбрал какой-то нестандартный/нелогичный подход: надо объяснить будущим поколениям — почему (Ваш пример, как я понимаю, как раз про это).
                                                                      Всё, других резонов написания комментариев/документации нет.
                                                                    –1
                                                                    11. Не стесняйтесь вставлять пустые строки, разделяя смысловые блоки в рамках одной функции

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

                                                                    На эту тему есть запись в блоге Егора Бугаенко «An Empty Line is a Code Smell».
                                                                      +4

                                                                      ага, инициализацию локальных переменных в одну функцию, цикл в другую, оператор return — в третью.


                                                                      По статье по ссылке — посмотрите сами на его пример отрефакторенного кода. Разве не хочется добавить простора? между методами, внутри метода lines()?


                                                                      edit: вот ваше сообщение состоит из 3 предложений, и вы все равно разбили их на два абзаца. Чем код хуже?

                                                                    +3
                                                                    В качестве дальнейшего изучения вопроса можно посоветовать книгу — Стив Макконнелл «Совершенный код».
                                                                      –2
                                                                      Её просто прочитать тяжело. А уж запомнить и начать использовать хотя бы часть — отдельный челендж.
                                                                        +1
                                                                        Вот Кнута читать тяжело. А Макконнелл так, чтиво для перекура.
                                                                      –1
                                                                      Не о том мы спорим. Каждому — свое. Правда ВСЕГДА нужно выполнять общепринятые нормы и правила, например, расстановка знаков препинания в тексте.

                                                                      Я почти всегда прекращаю чтение статьи, если там полно ошибок. Логика проста: если человек за 10 лет не выучил русский язык, то какова вероятность, что он выучит какой-то другой (С, Java, и т.п.) за 2-3 или даже 5 лет практики…
                                                                        +3
                                                                        Ошибочное мнение. Бывает что с годами язык забывается.
                                                                          +1
                                                                          Вот именно, Я на 100% с вами согласен!

                                                                          Просто недавно обсуждал одну тему: Разговор был о libc, в частности о musl libc. Так вот, я сказал, что это пример того, как НЕ надо писать код на языке Си.

                                                                          Ребята походу обиделись:)))
                                                                          Хотя, я всего-лишь предложил писать код для «обычных» людей, а не «заклинания» для компилятора.
                                                                          0

                                                                          Ваша логика ломается на нескольких моментах
                                                                          1) Для многих русский не родной язык (Я например из Украины, и в школе не изучал русский)
                                                                          2) Многих людей он может просто не интересовать, технари спокойно могут отдать приоритет точным наукам.
                                                                          3) Многие начинают изучать английский и другие языки, из-за чего знания русского может ухудшаться, а если этот человек иммигрировал — то и вообще пропасть.

                                                                            +1
                                                                            Я вот тоже перестаю читать такие статьи, правда, по другой причине.
                                                                            Если человек не привёл в порядок свой текст — это показатель непрофессионализма. Т.е. отсутствия ответственного отношения к тому, что человек делает.

                                                                            Оффтопик: а ещё, на мой взгляд, это неуважительное отношение автора к читателям.
                                                                            +2
                                                                            Максимально используйте инструменты:
                                                                            clang-format и голова о форматировании перестаёт болеть в 90% случаев.
                                                                            clang-tidy и уже не напишешь голую константу.

                                                                            Вот с комментариями вопрос сложнее. Какую пользу в файле Foo.java несет комментарий вида «Foo class implementation»?

                                                                              –1
                                                                              (промазал)
                                                                                0

                                                                                Классическим примером того как надо писать код лично для меня стал в далеком 1987 году код операционной системы Minix, где были соблюдены все эти рекомендации. Таким он остается и сегодня.

                                                                                  0
                                                                                  А мне ещё вот такая штука понравилась, когда можно картинки прямо в код вставлять. Всё проще читать, когда уже не вспомнить что на что влияет, например, в интерфейсе:
                                                                                  image
                                                                                    +5

                                                                                    STOYKA
                                                                                    STOEK


                                                                                    Вот это прям хорошо


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

                                                                                      0
                                                                                      На счёт параметров — согласен. Но это не мои. Из другой системы приходит, так что уж как есть. Хорошо ещё с регистрами договорились.
                                                                                      Конечно, опыт реальный. За основу брал плагин: https://marketplace.visualstudio.com/items?itemName=MsBishop.ImageComments
                                                                                      Пришлось его немного допилить, чтобы можно было copy-paste картинок делать, но даже в том виде, в каком он есть уже комфортнее работать. Есть у меня прога обхода принтеров и снятия с них показаний. Типов 30. На каждый принтер надо было указать из какого места что снимать. Вот такие картинки уже удобнее освежать в памяти:
                                                                                      image

                                                                                      Если что, вот ещё интересный плагин для readme.md под Visual Studio: https://github.com/madskristensen/MarkdownEditor
                                                                                      И как-то на пару они хорошо дополняют друг друга. Один в коде картинки показывает, в другом readme удобно писать. Почти лепота. )
                                                                                        0
                                                                                        Картинки всегда отосбражаются или при наведении мышки, например?
                                                                                        Если всегда — то это жесть.
                                                                                          0
                                                                                          Я писал как-то плагин отображения при наведении мышкой, не понравилось. Лучше поставить мелкий масштаб и если что, то смотреть уже при наведении мышкой. А то не видно, что картинка вообще есть. Но это дело вкуса. Вас же никто не обязывает вставлять картинку. Просто лично мне нравится, что картинка вообще есть. На поддержку программы сильно влияет. Забудете через полгода, что и как, а тут и картиночка имеется. Текст не всегда отражает суть, тем более, что контекст может сильно поменяться, а так хоть видно, что GUI изменился.
                                                                                          У меня на поддержке около десятка программ, и всякие плагины. Очень помогает.
                                                                                            0
                                                                                            А как она в git выглядит, картинка вставленная?
                                                                                              0
                                                                                              Если вы про gitlab или github, то, конечно, как текст:
                                                                                              image

                                                                                              Но ведь это не проблема комментария. Те же summary вас не смущают?
                                                                                              image

                                                                                              Если вы посмотрите на разные системы комментирования, то они туда много чего запихивают. Приглядитесь внимательнее.
                                                                                      • UFO just landed and posted this here
                                                                                          0
                                                                                          Напишите, для каких и чем подходит?
                                                                                        +4
                                                                                        Транслит в коде…
                                                                                        Не надо так, серьезно. Никогда.
                                                                                        0

                                                                                        В README.md или доках почему бы и нет, а в коде слишком много подводных камней. Кто гарантирует, что через пару лет этот код не будет поддерживать любитель vim/emacs, например? Плюс встаёт вопрос, класть ли их в репозиторий (скорее всего раздувая его в разы) или хранить отдельно (рискуя потерять). Да и за то время, которое уходит на снятие скриншота и прописывание урла, можно написать строчек десять текстового комментария.

                                                                                          0
                                                                                          что через пару лет этот код не будет поддерживать любитель vim/emacs, например
                                                                                          лично я думаю, что он будет только безумно счастлив увидев хорошо оформленный рисунок, который возможно объяснит ему всё гораздо лучше, чем сухой абстрактный комментарий.
                                                                                          Я хочу быть правильно понятым и не настаиваю на своём стиле комментирования, но надеюсь, что вы согласитесь, что написать хороший комментарий бывает ничуть не проще написания хорошего кода, а так же сделать хорошую картинку и скриншот тоже бывает очень не просто. Но я считаю, что на сегодняшний день отсутствие комментов в виде картинок не позволяет выйти комментированию на качественно новый уровень.

                                                                                          Да и за то время, которое уходит на снятие скриншота и прописывание урла
                                                                                          Вот! И это одна из главных проблем создания таких комментариев. Однако, это не значит, что этот недостаток нельзя преодолеть. Разве нет? Вот есть плагин "Image Comments", есть плагин "MarkDown Editor". Если их функции объединить (а эти плагины open source), то время на прописывание url-ов уже становится незначительным и его можно не брать в расчёт. (вставка картинки по Ctrl-V в любом месте кода)
                                                                                            0
                                                                                            лично я думаю, что он будет только безумно счастлив увидев хорошо оформленный рисунок
                                                                                            увидев

                                                                                            В виме сложновато картинки увидеть, в том-то и дело.

                                                                                              0
                                                                                              В таком случае в виме и результат-то сложновато увидеть.
                                                                                        0
                                                                                        Здесь несколько раз упомянули различные Code Style.
                                                                                        Соберу их в кучку:

                                                                                        Предлагаю в этой ветке собрать еще ссылок на такие же крупные рекоммендации, которые вам известны
                                                                                        +2
                                                                                        Статью пока не прочитал, но сразу возник вопрос. У автора открывающаяся фигурная скобка идёт с новой строки. Я тоже приверженец именно такого стиля форматирования кода. Очень удобно. Фигурные скобки на одном уровне отступов это блок вложенного кода.
                                                                                        Спрашивается, почему же тогда общепринятым считается стиль с открывающейся фигурной скобкой на той же строке (причем настолько, что в некоторых фирмах такой стиль просто требуют)?

                                                                                        А вообще для каждого более не менее серьёзного проекта (от 1000 срок), я всегда пишу обзор. Словесное описание алгоритмов, структура файлов и т.п. Это не заменяет комментариев в коде, а дополняет их, давая как бы взгляд на проект с высоты птичьего полета.
                                                                                          0
                                                                                          Мне кажется, что просто заголовок блока помещается на одну строку, например, условие в открывающая скобка. А в случае отдельной строки заголовок растягивается на целых две строки. В целом без разницы. Переключиться для чтения — минут 10 времени, для написания примерно 0, если использовать автоформат при сохранении.
                                                                                            0
                                                                                            Да нет, в удобстве разница большая. На мой взгляд во всяком случае. Я так вообще доставшийся мне сишный иди джавовский код всегда переформатирую как у автора статьи, и только потом начинаю с ним разбираться, комментирую, запускаю отладку и т.п. Дело вкуса конечно, согласен. Но мне кажется такой подход к форматированию куда естесственнее ни наглядней чем общепринятый. Да, лишняя строка. Но за счёт этого «покупается» прозрачность и ясность.
                                                                                              0
                                                                                              Аналогично, в первую очередь код, с которым приходится работать, привожу к общепринятому стандарту. Причем ручками, а не с помощью каких-нибудь плагинов для форматирования, заодно ближе знакомлюсь с кодом.
                                                                                                0
                                                                                                Работал я как-то с человеком, который, взяв любой тикет, первым делом переформатировал, причём ручками, под свои представления о прекрасном. В итоге имели два побочных эффекта: а) задача на полчаса превращалась в четыре и б) комит содержал помимо содержательной части, еще 50% переформатирования в соседних местах. Быстро понять, что было сломано, невозможно. Так что не надо так, пишите в том стиле, который уже есть в проекте, даже если он не общепринятый.
                                                                                                  0
                                                                                                  Я имел в виду, когда над проектом работаю я сам, конечно же. Часто это легаси, которое нужно заставить работать на новых версиях PHP. И я прекрасно знаю, как надо работать в команде и что такое системы управления версиями.
                                                                                                • UFO just landed and posted this here
                                                                                                    0
                                                                                                    А я встречал мнение, что Земля квадратная. Может вообще все те, кто ставит отступы и следует какому-то стандарту написания кода, страдают некой формой OCD? Ведь можно писать как попало, инструмент потом всё исправит, главное настроить его. Я объяснил, почему предпочитаю делать это вручную. Конечно, CR и пробелы в конце строк убираю регулярками, и там где куча однообразного кода и надо выставить пробелы после запятых (например) — тоже, и табы на пробелы регулярками меняю. Но в основном вручную.
                                                                                                    • UFO just landed and posted this here
                                                                                              0
                                                                                              В первую очередь надо следовать принятому в проекте/компании/языке стилю. Выбор, куда поместить открывающую скобку — это по большому счету вкусовщина и дело привычки.
                                                                                              Сам я начинал с С++ и открывающей скобки на новой строке, но потом долгое время пришлось писать на Java, где принято не переносить открывающую скобку на новую строку. Особой разницы на понимание кода при наличии привычки это не оказывает. А преимущества можно найти и там, и там. Например в первом подходе приятненько, когда соответствующие скобочки на одном уровне, зато во втором подходе блок кода зрительно прилеплен к соответствующему условию и отделен от последующих блоков.
                                                                                              Гораздо хуже, когда разные части одного и тоже проекта написаны в разном стиле.
                                                                                              0

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

                                                                                                0
                                                                                                А поддерживать это как?
                                                                                                  0
                                                                                                  Write only code.
                                                                                                0
                                                                                                а потом на проект приходит адепт Мета Программирования и все правила сливаются коту под хвост…
                                                                                                  0
                                                                                                  Правило про «только одну точку возврата» нужно только потому что люди пишут код одной большой портянкой. Искать еще один return в большой портянке — то еще удовольствие.
                                                                                                  Надо выбираться из помойки, а не делать помойку чуть более опрятной. Когда код должным образом декомпозирован, такого вопроса как писать один return или два вообще не возникает.
                                                                                                  Вот таким вот образом condition c двумя return-ами отделяется от вычисления, вуаля — проблема исчерпана.
                                                                                                  int fibonacci(int position)
                                                                                                  {
                                                                                                      return position < 2 ? 1 : fibonacciHigh(position);
                                                                                                  }
                                                                                                  
                                                                                                  int fibonacciHigh(int position)
                                                                                                  {
                                                                                                       int answer = 1;
                                                                                                       int previousButOne = 1;
                                                                                                       int previous = 1;
                                                                                                  
                                                                                                       for (int n = 2; n < position; ++n)
                                                                                                       {
                                                                                                           previousButOne = previous;
                                                                                                           previous = answer;
                                                                                                           answer = previous + previousButOne;
                                                                                                       }     
                                                                                                       return answer;
                                                                                                  }
                                                                                                  
                                                                                                  


                                                                                                  PS правда может возникнуть проблема именования функций, но это меньшее зло
                                                                                                    0
                                                                                                    PS правда может возникнуть проблема именования функций, но это меньшее зло

                                                                                                    Это как раз иногда большее зло. Например, в вашем примере, если бы я заранее не знал алгоритма расчета чисел Фибоначчи (и, с-но, что там должно быть внутри fibonacciHigh), то ваш код вызвал бы у меня… ммм… скажем так, очень сильное недоумение :)
                                                                                                    В рамках одной ф-и же такой проблемы нет, все сразу ясно.


                                                                                                    Надо все-таки не забывать, что код должен быть понятным в первую очередь для того, кто не знает, что он делает :)


                                                                                                    Кстати тот факт, что вы и сами сразу обратили внимание на нейминг после своего варианта — весьма красноречив ;)

                                                                                                      0
                                                                                                      Всегда можно дать избыточно понятное имя, например fibonacciForNumbersGreaterThan1. Привычка давать короткие непонятные имена происходит как раз из тех смутных времен.
                                                                                                    +4

                                                                                                    Очень хорошая привычка — перед каждым коммитом выполнять diff.

                                                                                                      +4

                                                                                                      Уж сколько раз твердили миру про то, что имелось в виду под SESE, а толку чуть: https://softwareengineering.stackexchange.com/q/118703/242401.

                                                                                                        +3
                                                                                                        Снабжайте файлы заголовками
                                                                                                        /*********************************************************
                                                                                                        * File: Foo.java
                                                                                                        * Purpose: Foo class implementation
                                                                                                        * Notice: © 1066 Foo industries. All rights reserved.
                                                                                                        ********************************************************/
                                                                                                        Тот, кому придется сопровождать этот файл, получит хорошее представление о том, с чем он имеет дело.


                                                                                                        Ну да, вот прочёл такой заголовок — и сразу легче стало.
                                                                                                        Писать название файла в файле — бесценно.

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


                                                                                                        Никогда о таком даже не слышал. И я очень сильно сомневаюсь, что эта информация поможет в представлении о том, с чем имеем дело.
                                                                                                          0
                                                                                                          У вас под рукой десятки проектов с сотнями похожих файлов? =)
                                                                                                          0
                                                                                                          Наличие комментария внутри функции (а не в заголовке) говорит о том, что функция не простая для понимания.
                                                                                                          Поэтому комментарий внутри функции, это первый признак, что что-то пошло не так.
                                                                                                            0

                                                                                                            Но половина проектов именно таких

                                                                                                            0
                                                                                                            Можно еще добавить про то, что комменты надо писать на языке команды. Когда встречаешь сложную бизнес логику, то ее итак сложно понять, а тут еще и коммент на ломанном английском.
                                                                                                              +1
                                                                                                              На каком именно языке команды? Если в команде три индийца, два китайца, один русский и один американец.
                                                                                                                0

                                                                                                                При условии, что в команде только русские или только китайцы, и проекты для внутреннего рынка. Таких проектов много

                                                                                                                  0
                                                                                                                  Может тогда и названия переменных/методов транслитом писать? ;)
                                                                                                                    0

                                                                                                                    Это перебор)

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

                                                                                                                      Короче говоря, моё ИМХО — программисты должны знать английский язык, и кодить, изначально предполагая, что с их кодом могут работать и иноязычные разработчики. Исторически получилось так, что как минимум в IT английский стал международным языком. Во всяком случае, такого количества документации, какое есть на английском языке, даже приблизительно нет на русском, китайском или испанском. И если программист не знает английский язык, его уже можно считать ограниченным программистом.
                                                                                                              +2
                                                                                                              Пишите короткие функции. В них легче разбираться. Можно сориентироваться в сложном алгоритме, если он разбит на мелкие фрагменты с содержательными именами, но это не удастся сделать в бесформенной массе кода.
                                                                                                              Пока функции были именно функциями, так оно и было. Но сейчас-то они методы, и описаны в лучшем случае в классах, а в худшем — в прототипах, причём композицию конечно же предпочитают наследованию, а рабочая структура программы собирается только в рантайме. И хрена с два вы поймёте, что и в каком порядке из этих 100500 функций вызывается, потому что из кода оно не очевидно, всё завёрнуто в сервис локаторы и фабрики. Сейчас вот ещё ECS (Entity-Component-System) стремительно входит в моду и пихается куда ни попадя, удачи вам разбираться в таком коде…
                                                                                                              Совсем плохо, если поверх всего этого там ещё и асинхронка с промисами, генераторами и подобным. Тут ход выполнения вообще головоломка, и чтобы мысленно «собрать» из пачки функций-однострочников полный алгоритм, без дебаггера вообще не обойтись.
                                                                                                                0
                                                                                                                Ну так используйте систему говорящих имен для асинхронных методов. И в комментарии напишите, куда и чем оно стреляет, название мишени.
                                                                                                                0
                                                                                                                Хочу сказать по поводу комментариев. Встречал такие варианты описания возвращаемого значения функции:
                                                                                                                item, если результирующий объект удалось создать; true, если во время работы не возникли ошибки; false, если полученные параметры имеют некорректное значение.
                                                                                                                — не надо так.
                                                                                                                  –3

                                                                                                                  Капец, вы серьезно?


                                                                                                                  Теперь ждём, когда кто-то опубликует пересказ "Букваря".

                                                                                                                    0

                                                                                                                    Ну все эти вещи какие-то пересказывания. Мне например нравится вот этот пересказ:
                                                                                                                    NASA C style guide
                                                                                                                    Похоже, что многие современные индусы программисты в авиаиндустрии его даже не видели.

                                                                                                                  Only users with full accounts can post comments. Log in, please.