Пользователь
0,0
рейтинг
5 сентября 2011 в 00:45

Разработка → Портрет Нуба перевод

Чем старше я становлюсь, тем менее важной становится запятая. Пусть читатель сам решает, где ему ставить паузы. — Elizabeth Clarkson Zwart


Примерно так я комментировал свой код двадцать лет назад (внимание, чуток драмы):

/*
 * Когда мы дойдем сюда, наша структура уже будет готова. 
 * К тому же, мы создали достаточно большой буфер, в который 
 * можно засунуть все входные данные, плюс есть немного места
 * про запас. Я не уверен, понадобится ли оно, но хуже не будет. 
 * Теперь нам надо обновить счетчик, предполагая, что клиент 
 * уже прочитал значение, но еще не использовал его. Сначала 
 * я хотел переложить обязанность инкремента на плечи вызывающего
 * кода. С другой стороны, это означает, что инкремент нужно делать всем, 
 * поэтому я решил, что будет лучше перенести его сюда. Но мы можем 
 * пересмотреть это решение позже, если вдруг кому-то из внешних функций 
 * захочется делать инкремент самому.
*/
counter++; // инкрементировать счетчик для потребляемого значения

/*
 * Теперь нужно просмотреть весь буфер с данными. Для этой 
 * операции нам понадобится еще один индекс, иначе перед 
 * выходом из функции мы потеряем начальное значение. 
 * Я хотел назвать эту переменную ‘ref’, потому что в некотором
 * смысле мы будем обращаться с ней как со ссылкой на данные. 
 * В конце концов я пришел к выводу, что самым лучшим  
 * названием для нее будет ‘pos’. Если что, я не против обсудить
 * это решение.
*/
char* pos = buffer; // начинаем наш обход данных

/*
Теперь, мы...
*/


Ну что, узнаете? А должны! Если быть предельно невежливым, весь код выше написал нуб. (Между прочим, если вы не знаете, кто такой нуб, значит вы — нуб).



Вот так пишут junior-программисты. В третьей главе замечательной книги Малькома Глэдвела “The Tipping Point”, рассказывается о рассуждениях 2-х летней девочки, которые поразительно похожи на то, что вы прочитали выше. Девочку зовут Эмили и она рассказывает себе истории, когда ее родители уходят из комнаты и оставляют ее одну. Вот, прочитайте выдержку:

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


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

Автор книги поясняет:

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


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

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

Для контраста, вот код, который я пишу сегодня:
(defun js2-parse-variables (in-for decl-type)
"Распарсить 'var', 'const' или 'let' утверждение или for-loop инициализатор.
IN-FOR истинно, если мы находимся в середине init-конструкции for-а.
DECL-TYPE это токен: или VAR или CONST или LET, в зависимости от контекста.
Возвращает распарсенное значение"
(let ((result (make-js2-var-decl-node))
      destructuring-init
      destructuring
      s start tt init name node
      (continue t))
  ;; Примеры:
  ;; var foo = {a: 1, b: 2}, bar = [3, 4];
  ;; var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
  (while continue
    (setq destructuring nil
          s nil
          tt (js2-peek-token)
          start js2-token-start
          init nil)
    (if (or (= tt js2-LB) (= tt js2-LC))
        ;; Деструктор, например, var [a, b] = ...
        (setq destructuring (js2-parse-primary-expr))
      ;; Название простой переменной
      (js2-must-match js2-NAME "msg.bad.var")
      (setq name (make-js2-name-node))
      (js2-define-symbol decl-type js2-ts-string))
    (when (js2-match-token js2-ASSIGN)
      (setq init (js2-parse-assign-expr in-for)))
    (if destructuring
        (progn
          (if (null init)
              ;; если (var [k, v] in foo) проинициализированны по-разному
              (unless in-for
                (js2-report-error "msg.destruct.assign.no.init")))
          (setq node (make-js2-destructuring-init-node :start start
                                                       :end js2-ts-cursor
                                                       :lhs destructuring
                                                       :initializer init))
          (js2-node-add-children node destructuring init))
      ;; простая переменная, возможно с инициализатором
      (setq node (make-js2-var-init-node :start start
                                         :end js2-ts-cursor
                                         :name name
                                         :initializer init))
      (js2-node-add-children node name init))
    (js2-block-node-push result node)
    (js2-node-add-children result node)
    (unless (js2-match-token js2-COMMA)
      (setq continue nil)))
  result))

В каком бы ужасе я находился, если бы я увидел этот код 20 лет назад. Боже, линии не отделены друг от друга! Некоторые из этих линий даже не прокомментированы! Какая ужасная функция! Я бы вопил “переписать все!!!”, если бы вдруг мне надо было с этим кодом работать.

Несмотря на то, что сегодня я пишу больше на Java или Javascript, я специально выбрал пример Emacs-Lisp функции, чтобы показать, каким отвратительно чуждым показался для меня двадцать лет назад ее код.

Если быть честным, то я согласен, это некрасивая функция. Это порт какого-то Java кода из парсера Javascript в Mozilla Rhino, который является портом какого-то C-ишного кода из парсера SpiderMonkey, который, скорее всего, взят из кода какого-то другого компилятора. У компиляторов есть т.н. родословная, и если ее отследить, то можно дойти до ассемблерного кода полувековой давности. Это я к тому, что все что связано с компиляторами скорее всего будет выглядеть некрасиво, если сравнить с “обычным” кодом.

Но даже если бы я писал на Java, мой код выглядел бы больше похожим на Emacs-Lisp, нежели на нубский код двадцатилетней давности. Он был бы плотнее: в нем было бы меньше пустого пространства и гораздо меньше коментов. И эти коменты скорее всего были бы предназначены для автоматического генератора API-документации. В общем, мой код сегодня гораздо более компактен.

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

Десять лет опыта превращают вас в подростка

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

То же самое происходит и в программировании. Младшие программисты, заработав пять-шесть лет опыта (и в чем-то до сих пор нубы), начинают городить управляторы миром, и через некоторое время вдруг оказываются в неустойчивом положении на вершине утеса, надеясь на то, что сейчас прилетит вертолет и спасет их. Они твердят себе “моя следующая система будет гораздо лучше” или даже падают с этого утеса — проект проваливается, людей увольняют или сама компания банкротится.

Я тоже проходил через это. Но тут надо сказать себе, что несмотря ни на что, даже
самому крутому программеру нужно иметь толику оптимизма и храбости, если он хочет добиться чего-то существенного. Следует всегда понимать и отдавать себе отчет в том, что каким бы вы не были опытным суперпрофессионалом, проект может завалится как без вас, так и с вами, стараетесь вы или нет.

Если вы, как менеджер по персоналу или владелец фирмы, вдруг читаете в чьем-то резюме слова о “5-6 лет опыта разработки”, то знайте — их нельзя перевести как “опытный”. Это переводится так: чувствующий свою неуязвимость малолетка, с вероятностью 50 на 50 напишет вам кучу дерьма, в которой потом не разберется ни его команда, ни он сам, и которую он вероятнее всего не один раз будет переделывать. Но все это в порядке вещей — любой разработчик бывает подростком в своей профессиональной жизни.

Восприятие компактного кода

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

Камнем преткновения здесь является то, что я называю “восприятие компактного кода”. Оно возрастает с вашим опытом, особенно если вы пишете ПО для разных областей применения и используете разные языки. Этот процесс очень похож на улучшение восприятия все более и более сложных книг у ребенка, которой проходит весь путь от азбуки с большими буквами и картинками до больших книжек, с мелким-мелким шрифтом. (Прогресс в конце-концов приведет к книге Finnegan's Wake, если вам любопытно). Нубы здесь — дети с низким восприятием, а у профи разумеется оно выше.

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

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

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

В общем да, это проблема.

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

Лично я предпочел бы разбираться в сжатом, сложном коде небольшого объема, чем в здоровой системе из тысяч файлов с коментами. Думаю, что после этого утвеждения большинство из вас скажут, что я капризный старый динозавр. Ну, может быть я и есть старый динозавр *р-р-р-р-р-р*.

Одержимость метаданными

Как всем известно, коменты — это метаданные. То есть информация о данных, в случае, если данными является ваш код. Люди очень часто думают, что коменты это всего лишь разновидность метаданных. Нет! Коменты и метаданные — это одно и то же.

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

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

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

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

Ха-ха.

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

Я проведу параллель с моделированием данных, которое является разновидностью статической типизации. Работали когда нибудь над проектом, где использовались большие объемы данных или серьезные БД? Наверняка вы замечали такой тип людей, которые считают себя гуру “моделирования данных” и гордятся своей карьерой моделистов. Как правило, они занимаются больше логическим моделированием, нежели физическим. Когда-то они начинали как обычные программисты, но вдруг на каком-то этапе своей карьеры они обнаружили, что их призвание — моделировать данные. Как будто бы они родились для этого.

Если вы знаете о ком я, то вы наверняка заметили и то, что такого рода люди всегда мешаются под ногами. Они сбиваются в банды, формируют всякие Комитеты Потоков Данных и Советы Схем Данных или еще какие-нибудь странные бюрократические структуры, предназначение которых одно — обеспечить их безопасность. Они тратят кучу времени на препинания с обычными программистами, которым завтра надо сдавать проект. Особенно сильно страдают от них субподрядчики. Вроде как они не связаны с основной доходной деятельностью компании, но по несчастливой случайности им оказалось нужно что-то поправить в БД.

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

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

Хардкорщики-моделисты часто страдают одной из форм наркомании, называемой “одержимость метаданными”. О, это соблазнительный процесс. Он не заставляет вас никуда торопиться. Вам не нужно делать ничего сложного. Для каждой новой вещицы будет своя коробочка. С другой стороны, использовать немного метаданных имеет смысл (будь это коменты, статические типы или модели данных). Люди могут общаться, используя термины из модели, или машины могут использовать эти метаданные, чтобы потюнить производительность программ. Тем не менее, удивительно большое число разработчиков в отрасли слишком сильно перегибают палку, вместо реальных дел предпочитая эти дела описывать.

Одержимость метаданными применима и к обычным программистам. Код — это данные, и данные — это код. Эти понятия связаны неразрывно. Данные в ваших генах — это код. Чертежи здания — это код. Понятия, повторюсь, на самом деле неразличимые, они связаны между собой фундаментально через восприятие Интерпретатором, который в свою очередь является сердцем Computer Science. Метаданные — это больше почки Computer Science. Можете продать одну и жить спокойно дальше.

Ползучая бюрократия

Как мне кажется, самая главная причина, почему такие языки как C++/Java (в противоположность всяким динамическим Perl/Python/Ruby или уж совсем гиковых Modula-3/SML/Haskell) стали повсеместно использоваться в индустрии, заключается в том, что они оба одинаково угождают всем разработчикам — как уверенным в своих силах, так и неуверенным.

Предположим, есть две группы программистов. Одна пишет на плюсах, используя стиль языка С с буферами и указателями, но при этом ограничивает введение новых пользовательских классов. И другая группа, которая тратит недели, вымучивая основанную на шаблонах и прочем метапрограммировании систему типов, пытаясь смоделировать на ней что-то, что сложно моделируется или не моделируется этими шаблонами вообще. Как вы думаете, какая группа сделает полезной работы больше? Мне кажется, что первая. Все что делают люди из первой группы — перемещают данные туда сюда и запускают алгоритмы, а плюсы помогают им сгладить всякие неровности и шероховатости — накрутить структур данных для публичного API, например. Это гораздо полезнее, чем трата времени на то, чтобы научить самописную систему обработки ошибок правильно ловить всевозможные программные исключения. Конечно, очень здорово и весело писать подобную всемогущую модель, но на практике достичь более менее приличного результата потребует гораздо больше усилий, чем оно того стоит.

Точно так же, в стиле C, можно писать код и на Java. Многие опытные разработчики так и делают. Java более привлекательна, чем C, за счет ООП из коробки. Прошу не путать — ООП все же слегка ортогонально системе статических типов. Вам не нужны статические типы, чтобы пользоваться OOП. Более того, концепт ООП был рожден и обкатан много-много лет назад как раз в динамических языках, таких как SmallTalk и Lisp, задолго до изобретения всякой статической шелухи. Важными элементами ООП являются синтаксис (да даже он не так важен) и объектная модель, представляемая в рантайме.

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

Почему Perl, Python и Ruby и т.п. так непривлекательны для большинства разработчиков? Потому что они заставляют разработчиков проделывать работу до конца. Что еще хорошо в этих языках — в них достаточно сложно накрутить моделей и вселенских управляторов (хотя некоторые люди пытаются). В общем и целом, они (как и обычный C) заставляют вас проделать все что нужно, чтобы добиться конечного результата. Разумеется, такие языки очень непопулярны у одержимых метаданными нубов. Смешно, я помню, как я бесился, когда давным-давно Larry Wall обозвал всех java-разработчиков школотой. Как показал опыт, это немного не так… но только совсем немного.

А Haskell, OCaml и его производные? Они тоже исповедуют путь 45-летней давности, предлагаемый Академией Статического Типизирования, то бишь заставляют разработчиков моделировать все и вся. Разработчики это ненавидят. Эти языки никогда-никогда-никогда не добьются никакого коммерческого успеха, точно так же как его не добился концепт “семантического веба”. Вы не можете заставить людей создавать метаданные для всего, с чем они хотят работать. Они будут ненавидеть вас за это.

С моделированием связана еще одна очень актуальная проблема. Модели, которые получаются в результате этого процесса, часто оказываются “неправильными”. Наверное, это сложно понять с самого начала — как может модель быть неправильной? Код (или данные), живут в этой модели и подгоняются под ее правила и ограничения, поэтому и код и данные корректны с точки зрения модели. Однако, модель “неправильная” тогда, когда с ее помощью нельзя отразить реальные вещи из какой-нибудь области, под которую эта модель создавалась. Взять ту же java — всегда, когда вы хотите использовать множественное наследование или примеси, вам нужно изменять представление вещей у себя в голове, чтобы они подошли под ограничения и правила мира java. Вы портите естественный дизайн, поэтому java — “неправильная”.

Важным теоретическим понятием в мире моделирования для моделистов является “звучание” систем типов. То что звучит — это хорошее, годное, а что не звучит — стало быть, наоборот. О, как они любят рассуждать, что звучит, а что не звучит. Java и C++ — не звучат. Но что теоретики-моделисты не понимают, так это то, что пока они не придумают систему, которая была бы корректна в понятии “правильности” (я описал его чуть выше), они будут раз разом фрустрировать своих пользователей, которые наверняка предпочтут более гибкие языки. (И да, scala-исты, нельзя описать весь мир с помощью списков свойств — нужно быть еще проще).

На сегодняшний день, чем больше система звучит, тем больше она “неправильная”. Это первая причина, по которой C++ и Java являются такими успешными: вы можете перестать пользоваться моделью типов, если вдруг она начнет вам мешать.

Вторая причина непосредственно связана с возможностью этих языков создавать пользовательские типы данных. Но, обращаю внимание, далеко не потому, что от них можно получить практическую пользу при создании систем (а польза есть). Причина, по которым C++ и Java так популярны, заключается в том, что предлагаемая ими статическая типизация позволяет бросить заниматься по-настоящему полезными делами и начать бить в нубские баклуши. То есть, моделировать вселенную или писать для самого себя истории.

Java просто переполнена такими нубами. Нет ни одного книжного магазина или форума, где бы их не было. Их можно найти даже в туалетах в некоторых компаниях. Построить модель всего на свете нельзя: это формально невозможно и на практике приведет в тупик. Но они пытаются снова и снова, и, точно так же как и моделисты данных, убеждают своих коллег и вас заниматься этим. А если вы отказываетесь — вы Преступник.

Это приводит их на “утес” нубства снова и снова. И, раз они по своей сути малолетки, они не могут понять, что же они сделали не так. У систем типов есть свой вес и своя мера инертности. Такие системы нужно создавать, их нужно поддерживать, тратить время на изменение и на определение обходов всяких проблем, если таковые обнаруживаются. Эти системы — просто коменты и ничего больше. Такие метаданные эквивалентны вспомогательной документации. Ну а статические системы типов — это то, что становится на пути гибкости, быстрой разработки и расширяемости.

В качестве иллюстрирующего примера я взял Apache Struts и WebWork и написал кучу слов про эти фреймворки. Но все удалил. Вместо того, чтобы тратить кучу времени, лучше почитайте, что сами разработчики Struts пишут про свой фреймворк в статье “Эволюция Struts 2”:

…архитектура Struts 1 не позволяет вносить во фреймворк значительные улучшения и так же имеет значительные ограничения функциональности. В частности, в ней не хватает возможностей Ajax, быстрой разработки и расширяемости.


Struts 2 заменил собой Struts 1 по причинам, описанным в цитате. Через некоторое время по тем же причинам WebWorks заменил собой Struts 2.

Несколько слов стоит посветить JUnit 4. Разработчики этого фреймворка, являя собой пример эталонного нуба, решили, что представленные в Java 5 аннотации — решение всех проблем человечества. Не знаю, смеятся или плакать, но они перенесли весь свой код из нормальных методов в тела аннотаций — самое абсурдное применение метаданных, что я когда-либо видел. Но хватит об этом. Кому интересно — погуглите, в инете много информации по этому поводу.

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

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

В мире есть тысячи opensource-ных проектов на Java, которые были задизайнены программистами-нубами. Эти проекты испытывают какие-то постоянные затруднения, и как я всегда думал, в основном из-за Java. Но сегодня можно с уверенностью сказать — даже несмотря на невзрачность Java как языка (который, по-моему, стал тревожно похож на Pascal), виной всему культура разработки. Как только одержимость метаданными и прочая бюрократия начинают вползать в ваш проект, команду или организацию, очень сложно найти в себе силы противостоять им.

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

Как правило, опытные программисты игнорируют таких людей и занимаются делом.

Решения и соглашения

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

При моделировании следует придерживаться тех же правил, что и при комментировании кода: не пытайтесь смоделировать все на свете! Оставьте код в покое — пусть он сам за себя говорит.

Например, предположим, что вам нужно вернуть два значения из функции в Java. Этот язык не поддерживает возвращение нескольких значений из функции напрямую. Так что же вам делать? Создать специальный класс MyFunctionCallResult с двумя полями ValueOne и ValueTwo (ну, может еще названия полей поменять соответствующим образом)? Или же просто вернуть вызывающему коду массив из двух элементов (может быть даже элементов разных типов) и пусть он сам разбирается, что с массивом делать?

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

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

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

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

Постскриптум

Оставляю коменты включенными. Ну, до тех пор, пока мне в почту не повалятся ссылки “нажми-на-мой-спам”. Мне очень любопытно, что из всей этой затеи получится. Это был очень трудный пост для меня. Мне сложно было его писать, я очень много раз его правил. Мне кажется, что я не очень ясно высказал свою точку зрения. Я так же не уверен, что смог достучаться до одержимых метаданными людей и показать им, что у них есть проблема. Хотя, раз уж теперь они знают, что где-то рядом ходят другие люди, которые имеют такие проблемы, то это уже хорошо.

Не стесняйтесь, высказывайте свое мнение!
Перевод: Steve Yegge
@acerv
карма
97,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (171)

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

    Скорее всего, бедные те, кто будут после меня, но сам я не испытываю проблем в чтении с листа вменяемого кода.
    • +3
      Ага, аналогично никогда особо не комментил код. Ну, только стрёмные оптимизации разве что, да пометки вроде FIXME, TODO, HACK да функции в общем (и то не все). В основном комментарии — это закомментированный код :) Код должен «читаться» и так. А если не читается, то что-то тут не так.
      • +4
        А это такая природа программиста — пока пишет на текущем уровне *ему* все понятно. Уж лучше бы порой сомневался комментами // I feel it smells but can't imagine better approach
        • 0
          Ну, вот в таких местах я ставлю // FIXME: description how to fix или // HACK: dirty hack to do smth если пока не представляю как по-нормальному сделать.
          А насчёт всё понятно — описания классов и методов обычно хватает, или если сложный блок — особенно, если оптимизировано до состояние непонимания — тут да, по-любому надо.
      • –2
        Комментированый код существовать не должен. Для этого существуют системы контроля версий.
        • +1
          Понимаете, есть теория, а есть практика. Да, в теории всё замечательно — DCVS вроде git или mercurial… а в реальности — svn. поэтому комментированный код будет. Особенно если идёт разработка вот сейчас — этот коммент будет удален до коммита, но пока — оно проще.
          • +2
            У меня в практике: сейчас меркуриал, перед этим проект с гитом, перед этим проект с сабвершеном и hgsubversion, перед этим еще два с меркуриалом. Да, три из них я убедил юзать меркуриал (один с нуля, один с свн, один — самый последний — с базара), но усилия того стоили. :)
            • 0
              Ох, не сомневаюсь, что стоили :) В принципе о mercurial уже думали, но пока тихо :(
    • +11
      «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.» (С) Стив Макконнелл

      С такой точки зрения понимание где уместно ставить комментарии иногда достичь легче. :)
      • –4
        Как замечательно, что этот психопат я!
  • +13
    Действительно, разница в восприятии опыта у нас и на Западе различается.
    [...] вдруг читаете в чьем-то резюме слова о “5-6 лет опыта разработки”, то знайте — их нельзя перевести как “опытный”. Это переводится так: чувствующий свою неуязвимость малолетка, с вероятностью 50 на 50 напишет вам кучу дерьма

    А у нас 5-6 лет опыта — и уже сеньор/тимлид/архитектор.
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Автор, Стив Йегг, вроде как разработчик с опытом лет в 20-25. Он видел появление плюсов, восход Джавы, появление Джаваскрипта как языка, и я лично видел его код в живых открытых проектах. Это не закостеневший зубр, а очень и очень толковый разработчик, быстрый, внимающий трендам. Это не считая того, что известный блоггер.

        Что совсем уж редко — он так и не стал одним из этих консультантов.

        Так вот. С его колокольни все мы здесь в лучшем случае начинающие :)
    • +8
      Хватит уже делить на «на запад» и «у нас». И там долбоебов хватает и тут. И у них есть крутые тимлиды и у нас.

      А опыт тем более ничего не показывает. Все зависит от того, на сколько была агрессивной среда, в которой развивался специалист. Скажем, если человек попал стажором в Эбби, то за 5-6 лет он вполне может стать тимлидом, а продвинутым кодером будет точно. А вот если он попал в какой-нибудь шараш-монтаж, то возможны варианты.
    • +2
      Вопрос еще в том, что именно тут считается опытом…

      Вот считается ли опытом участие в школьных олимпиадах по программированию, написание дома всякого софта разной степени бесполезности, обучение в универе по специальности наконец? ;-)
      • 0
        Опыт работы и опыт хобби — очень разные вещи.
        • +3
          Опыт работы и опыт программирования — тоже очень разные вещи.
  • +9
    Интересно… рад, что не я один люблю экономить на комментариях. А то начальник недавно попросил добавить побольше комментов к коду, дабы последующим было легче, так мне пришлось долго думать где же их впихнуть, так как везде имена функций и переменных говорящие, разве что ветки условных операторов обозначить и не очевидные места алгоритмов. Вообще, как по мне, так хороший код почти не надо комментировать.

    А с моделированием главное вовремя остановиться. Я делаю просто: если после добавления классов я смогу забыть о том, что у них внутри — добавляю. Причем добавляю как можно меньше классов, которые полностью описывают какой-то кусок проблемы, но если можно проблему внутри разбить еще раз, будет на каждую подпроблему свой класс. Может правильные подход, может нет, но как-то работает:)
  • +1
    Don't try to model everything!
    Вот об это я уже спотыкался.
  • +31
    Для контраста, вот код, который я пишу сегодня:

    В каком бы ужасе я находился, если бы я увидел этот код 20 лет назад.

    Почему-то кажется, что в ужас нужно бы придти и сейчас… Код нужно писать для людей, а не для машин.
    • 0
      Он был написан для людей… А потом его перевели сначала на C, потом на Java, потом на EL. И получился ужас.
      • 0
        Он же все равно его писал.
  • +2
    20 лет назад я не писал комментариев, так как 1) объемы носителей были малы и комментарии жрали драгоценное место и 2) я и так помнил наизусть все свои алгоритмы, а другим до них не было дела :)
    Сейчас я не пишу комментариев, так как 1) я научился использовать простые алгоритмы и писать простые программы (не брезгуя использованием готовых библиотек) и 2) программы для меня — инструмент, часто одноразовый, нет нужды комментировать или даже просто хранить их. Надо будет — новые напишу, лучше прежних :)
  • +51
    Новичок, который комментирует каждую строчку хотя бы так — это уже идельный новичок. Обычно новички свой код вообще не комментируют.
    • 0
      Опять же. Он о других новичках. Для него 3-5 лет комерческого опыта это новичок. У таких «новичков» порой бывают бзики. Использование паттернов где надо и не надо, оверкоментинг, супергибкие архитектуры и прочее.

      А для нас новичок с 3-5 лет опыта — это как вы верно подметили «идеальный новичок»
      • 0
        Я всегда считал, что новичок — это студент, взятый с 4-5 курса, например. А 3-5 лет опыта — это уже не новичок.
  • +9
    Хочется напомнить автору, что по себе людей не судят, но он программист и нашел алгоритм…
    • +21
      Просто автор бросил писать длинные занудные комментарии и начал писать длинные занудные статьи.
  • +49
    Гоблин-аргументация: выдумать в статье подростка (который по психологическим причинам будет больше говорить об авторе, чем об оппоненте) и спорить с ним. Подросток при этом проигрывает, потому что подросток, ну это же очевидно, что тот, кто ужаснулся от кода автора — нуб, то ли дело блоггер-автор.
    • +8
      А эта гоблин-аргументация идёт, знаете ли, из древней античности, от Сократа и Платона.
      Нормальный жанр для статьи, проверенный временем. ;-)
  • 0
    никогда не понимал чем люядм которые считают себя «папками или гуру» мешают развернутые коментарии.
    Да я иногда например тоже коментирую каждую строку, и даже $i++ коментирую, никогда не понимал чем это плохо?
    • +6
      Например — сложный алгоритм. Предпочтительнее видеть его на одном экране, чем размазанным на многих.
      • +6
        ну в сложном алгоритме имхо разобратся быстрее и проще если он отлично закоментирован, я конечно понимаю что хороший код не нуждается в коментариях но не всех у нас iq выше 120
        • 0
          Конечно все зависит от сложности алгоритма, но лично мне обычно коменты мешают разбираться в алгоритме. Отдельный случай (но это уже конечно клиника) — когда коменты не соответствуют коду.
          • 0
            Это не такая уж клиника, как может показаться.
            Не каждый программист поддерживает чужие комментарии. Да и свои не всегда.
            Поэтому, IMHO, лучше следовать мантре «Читай код».
            • 0
              Я же это и имел в виду — imho, обычно комментарии нисколько не помогают разобраться в коде.

              > Не каждый программист поддерживает чужие комментарии. Да и свои не всегда.
              Это уже вопрос культуры. Раз уж начал комментировать код — будь добр поддерживать эти комментарии в актуальном состоянии. Иначе это просто свинство по отношению к коллегам.

              P.S. За статью спасибо, прочитал с большим удовольствием.
      • +5
        Хозяйке на заметку: если ваш редактор не позволяет свернуть комментарии и блоки кода, выкиньте его.
        • +1
          покажите мне редактор, который сворачивает // комментарии, пожалуйста
          • 0
            • 0
              Ой, простите, неверно понял ваш комментарий
            • +1
              Можете показать пример(картинку) где в Notepad++ сворачивается комментарий вида "//"? Я не вижу там такой возможности. Другими редакторами не обладаю, поэтому и проверить не могу.
              • +2
                Я же написал, что неверное истолковал ваш комментарий, не заметил, что вы про "//". Так что не обращайте внимания ) Хотя, думаю, если хорошо подумать, то в VIM можно сделать сворачивание таких комментариев.
              • 0
                а как его сворачивать, если это ОДНОСТРОЧНЫЙ комментарий? вот /*… */ такое сворачивает
                • 0
                  Подразумевается несколько идущих подряд однострочных комментариев
                • 0
                  Можно его просто не показывать. Вим можно такому научить довольно-таки легко.
          • +1
            IntelliJ IDEA
        • –1
          Вот ещё! Вместо того, чтобы просто видеть то, что нужно я буду комментарии сворачивать-разворачивать.
        • +3
          Возможность сворачивать — это фича. Она, как и наличие коментариев (методанных), не влияет на качество кода. Мне нравится мысль Фаулера: если для объяснения кода нужен коментарий попробуйте отрефакторить его (почти дословно).
          • 0
            Фаулер хорошо понимает принципы проектирования, эт точно.
            Кстати, это очень хорошо работает. Не нашел ни одного случая, где путем рефакторинга не удалось бы избавиться от комментариев и излишней запутанности кода.
    • +3
      С точки зрения автора:
      1. Это дает возможность писать непонятный код и заставляет вести две параллельных ветки: литературную и на языке программирования.
      2. Очень редко это действительно нужно. Например i — это что такое вообще? Может someIdx было бы лучше и избавило бы от комментария.
      С другой точки зрения:
      3. Понимать, что этот код делает становится сложным: если я открыл ваш код, я или пытаюсь узнать, что функция делает и абстрагироваться от реализации (тогда достаточно коммента в начале), или пытаюсь высмотреть у вас там ошибку, и построчные комментарии конечно же об ошибке мне ничего не скажут.
      4. Намного проще становится делать хаки и прочее — а чего, комментарий ведь выше описывает, что делается. Если бы комментариев было мало, откомментированный хак был бы заметнее.
    • +6
      Если в коде используются понятные имена функций и переменных, то простые алгоритмы просто нет смысла комментировать, код уже содержит всю информацию.

      Например:
      i++; //увеличиваем количество клиентов

      Можно написать как:
      ClientsNumber++; //увеличиваем количество клиентов

      В первом случае мы описываем, что же мы делаем в комментах, во втором же случае мы пишем два раза одно и то же.
      • +4
        Писать самодокументируемый код очень удобно и полезно, но полностью от комментариев отказываться тоже глупо. Я например, стараюсь разбивать код на некие логические блоки длиной 4-10 строк и разделять их абзацами, и перед каждым таким блоком стараюсь вставить однострочный комментарий описывающий что в нем делается. Так намного проще даже мне самому ориентироваться в коде. Ну а внутри блока, по именам переменных и функций и так все понятно.
        • +2
          Месяц назад, мне захотелось в первые за год написать комментарий на строку кода (внутри метода). Я ее написал, пошел дальше. Подумал, вернулся и разделил строку на две или три. Комментарий удалил. Завтра, если я ее увижу и подумаю, что она все равно сложная — еще чего-нибудь сделаю.

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


            Используем давно известный принцип единой ответственности. Если есть трудности с определением, выполняет ли предложенный код одну или несколько задач, советую прочитать «Чистый код».
            • 0
              Только проблема остается все та же, как определить простейшую задачу, которую не надо разбивать дальше?

              Т.е. есть например есть игра в которой надо нарисовать персонажа. Что есть простейшая задача, которую не надо разбивать на подзадачи? Нарисовать персонажа? Нарисовать руку/ногу? Нарисовать отдельно тело отдельно одежду? Нарисовать поверхность? Нарисовать треугольник?

              Код, который рисует персонажа отвечает только за рисование персонажа, но делает много разного для этого. Если же все дробить на мельчайшие части, то объем кода сильно растет и его поддержка занимает больше времени.
              • 0
                Разберу случай с персонажем:
                • Работа с движком — инкапсулируется в отдельный класс>
                • Получение простейших компонентов, таких как линии, плоскости, примитивы — все в отдельный класс, на каждый компонент — отдельный метод.
                • Элементарные преобразования — в отдельный класс, на каждое преобразование — отдельный метод.
                • Различные сложные компоненты и преобразования также по отдельным классам.
                • Рисование каждой части тела — в отдельный метод. Возможно, сложную часть тела типа «рука» имеет смысл разбить на зап. части, по методу на каждую.
                • Рисование первонажа — отдельный метод.


                Как разбивать (и разбивать ли) внутри данных методов — сильно зависит от того, какой код будет получаться в итоге. Правила, которыми имеет смысл руководствоваться, давно известны и написаны, например, у Макконнелла.
                • 0
                  Ваш подход — это один из многих вариантов. Как альтернативу можно привести по классу на каждый элемент и их иерархия: персонаж содержит руки/ноги/etc и свое относительное расположение в сцене, руки/ноги/etc содержат внутри геометрию и свои положения в сцене, геометрия содержит треугольники и их положение. Тогда чтобы нарисовать надо вызвать метод персонажа, а все остальное иерархически будет происходить внутри. Так что все далеко не так однозначно как кажется:)

                  Да Вы и сами говорите:
                  «Как разбивать (и разбивать ли) внутри данных методов — сильно зависит от того, какой код будет получаться в итоге.»

                  То есть нельзя точно сказать, как разбивать тот или иной код. Один человек сделает так, другой эдак. Правила то есть, но это скорее не алгоритмы с точным результатом, а эвристические правила, которые подсказывают куда двигаться.
              • 0
                «Рисование персонажа» — это одна ответственность, да. Поэтому не надо туда сваливать рисование треугольника — это уже другая ответственность :-) Понимаешь принцип?
              • 0
                Если же все дробить на мельчайшие части, то объем кода сильно растет и его поддержка занимает больше времени


                Не согласен. Необходимо просто дробить таким образом, чтобы взгляда на имя метода и набор параметров было достаточно для того, чтобы вспомнить, что оно делает. Тогда навигация до нужного места происходит интуитивно, без лишнего обдумывания.
                • 0
                  Хотел поспорить сначала, потом подумал, может мы оба правы:)

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

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

                  И еще этот метод нельзя применять при написании первой исследовательского кода, это уже мой личный опыт. Я честно пытался разбивать все на части красиво, но в результате слишком много времени тратилось на поддержку. Видимо поэтому я и против того, чтобы всегда делать все правильно и красиво:)
      • +1
        Во втором случае код говорит увеличить номер клиента (какой именно номер ??), а коментарий говорит увеличить кол-во.

        numberOfClients++; — так пожалуй более честно
        • 0
          Ваша правда, плохое имя дал. Но идея та же:)
    • +2
      Это мешает читать код.
  • +5
    Золотые слова:
    Код нужно писать для людей, а не для машин
    • +2
      Надо, только не всегда такое возможно… (но это скорее исключение, чем правило, например GPGPU где вызов функции = растрата регистров на стек)
      • 0
        Понятное дело, там, где идем война за регистры и кешы процессора, там действуют другие правила :-)
        • 0
          hex код не надо комментировать, это для машин, а в исходники я предпочитаю вставлять комменты, хотя бы для того, чтобы знать, что означают выводы порта контроллера (которых десятки), так как это не поддается особой логике и склонно к изменению (аппаратному, например).
  • –1
    у мну обычно дилемма. либо описать очень подробно каждую строчку, либо не писать вовсе. ибо я считаю свой код понятным итак, и тогда либо комменты нужны полным профанам, либо не нужны вовсе. ну и еще я не люблю переменных a, b, c и т.д. максимум что я использую, это i для for циклов.

    кто я? подросток? нуб? еще кто похуже?
    • +20
      Вы «мну».
      • –6
        я «гну» тогда уж ) парнокопытное )
  • +6
    Еще ни разу не видел, чтобы кто-нибудь написал о комментировании лучше Макконнелла. И эта статья — не исключение.
  • +17
    >> Боже, линии не отделены друг от друга! Некоторые из этих линий даже не прокомментированы!

    Боже, линии! (хотя может переводчик не программист)

    >> Если быть честным, то я согласен, это некрасивая функция.

    Если быть честным, то привел бы автор пример своей красивой функции, чтобы видно было, как он пишет сейчас. А то может он и не «повзрослел» вовсе.
    • 0
      переводчик тоже должен учитывать контекст и использовать адекватный словарь
  • +3
    В кружке информатики при Дворце Пионеров, а потом и в университете видел очень много нубского кода(не считая своего). Комменты отсутствовали напрочь.
  • +5
    Было такое. Одно время я доводил себя до состояния, когда каждая фукнция должна была занимать не более 20 строчек и иметь не менее 5 строк комментариев, а пустыми строками она отделялась от соседей так, чтобы на экране была только одна функция.

    Кстати, я так и не стал хорошим программистом (хотя способен кодить на нескольких языках) и стал сисадмином (для которого подобная обстоятельность — скорее благо, чем зло).

    И, кстати, потому мне тяжело писать на питоне — там слишком много нужно программировать, и слишком мало выполнять всяких простых ритуальных движений, вроде проверки успешности выделения памяти, организации списка и т.д.
  • +2
    Хорошо, если новичок комментирует хотябы каждую пятую строчку. А то обычно они вообще не комментируют код.
    • 0
      А то обычно они вообще не комментируют код.


      Это не плохо. Плохо обычно в том случае, когда этот код представляет собой кашу.
  • +5
    Между писаниной простого плоского кода, который растягивается на очень длинные листинги, и писаниной высоко-сложного кода, который растягивается на очень длинные листинги, где-то в районе посреди есть оптимальная позиция, имеющая минимальный листинг.

    Тут я с автором совершенно согласен. Если я неверно понял его предупреждение не писать плоский код. ;-)

    Читать Властелина Колец, где для понимания текста читатель обязан сначала прочесть 50 страничную энциклопедию, прямо-таки алфавитно упорядоченную, я отказался. И у меня ушло 60 минут разобраться в короткой фразе «рецессивный аллель влияент на фенотип, только если генотип гомозиготен», которая читается за 10 секунд.

    То же самое когда определяется сложная модель — вводится гигантский «prerequisites» для чтения. В конце концов задача решается, конечно же, в одну строчку, но… Длина листинга же.

    Плоский код, с другой стороны, сродни фортрану или ассемблеру. Длинные простыни примитивных операций во время чтения которых ты пытаешься перевести их на термины задачи, но забываешь с чего дело началось 5 страниц назад. Почти обязательно он будет в стиле «спагетти». Каждая отдельная строка понятна, но общая картина в голову не укладывается. Длина листинга же…

    При этом я не имею в виду obfuscated c programming, где используются трюки навроде «while (*d++ = *s++);», (который объясняются в K&R на трёх страницах). Это третья шиза, но она встречается гораздо, гораздо реже.

    Сам на С++ пишу «в стиле С», так как практические задачи универсальных абстракций не требуют. И комментирую одной-двумя строками следующий блок в 5-10 строк.
    • +1
      Ваша фраза про «рецессивный аллель» мне напомнила о динамичесих и функциональных языках.

      Будучи студентом-биоинформатиком, смысл я понял за пару секунд, но это мне напомнило некоторых коллег-сишников, которые долго-долго пытались понять штуки вроде map{}.reduce{} в Ruby или мои собственные попытки вникнуть в таинства концевой рекурсии в Scheme.

      Скорость и легкость понимания кода все же очень сильно зависит от опыта.
      • +3
        Это школьная программа.
        • 0
          Хм, не знал, что в общеобразовательной тоже есть — я был в биохим-параллели.

          К слову, вещи вроде map/reduce, на мой взгляд, тоже вполне тривиальны — и тем не менее регулярно вызывают затруднения, как и «школьная программа» у автора первого комментария.
    • +5
      «Читать Властелина Колец, где для понимания текста читатель обязан сначала прочесть 50 страничную энциклопедию, прямо-таки алфавитно упорядоченную, я отказался»
      Есть мнение, что вы что-то делаете не так. ВК прекрасно читается и без этого.
      • +1
        Тут путают ВК и «Сильмариллион». Вот тот да, требует изрядныз усилий порой.
      • 0
        А вообще, ВК с точки зрения сложности восприятия и количества информации, которое нужно удерживать в голове, чтобы понимать что вообще происходит, читается куда проще чем, например, «Хранитель Мечей».
  • +13
    Эпичный троллинг. Напомнило моего первого начальника который 30 лет писал на ассемблере и утверждал что классы (в С++) — это баги, и писать надо только C-style. Правда он, в отличие от автора текста, не троллил а просто дурак был (чем погубил не один проект)

    И да, про комментарии. В них, как было обмусолено тысячу раз, нужно писать что, а не как. Тогда и описаний на полэкрана не будет.
    • +1
      Классы — штуки реально хорошие, когда пишешь либу.

      Ещё лучше, когда берёшь чужую тщательно продуманную — ведь VCL толкнул Delphi очень далеко вперёд.

      Но стоит задуматься — нужна ли в этой конкретной сегодня программе эта моя самописная либа. И что в неё таки правильно оформить.

      Всегда можно дойти до маразма
      main() {MyClass.SolveTheProblem();return;};
      но надо ли? действительно ли цикл жизни моего софта предполагает 10-летнее использование с пятикратным ростом функционала, или 2-3 года и две модификации хватит?
      • +7
        main() {MyClass.SolveTheProblem();return;};
        Вот она — Большая Красная Кнопка!
        *аплодирует*
        • 0
          Вот, почти оно:

          static void Main()
          {
          Application.EnableVisualStyles();
          Application.SetCompatibleTextRenderingDefault(false);
          Application.Run(new Form1());
          }
          • +2
            Классы-шмассы…
            Пишете свой язык. А потом в нем вот так:

            do;

            Точку с запятой можно опустить.
            • +1
              Дык это ж системная консоль, написана уже
    • +1
      Это «что» лучше тоже писать в коде ) например, в именах функций, методов, полей и классов.

      Меня больше зацепили в статье не комментарии, за которые ухватились куча народу, а само понятие «метаинформации». Т.е. самодокументирующий код пишут нубы? Думаю, с автора (не статьи, а исходника) таки нужно взять листинг его собственного кода, и посмотреть, кто он такой.
  • +19
    Дочитал до середины, надоело, прочитал «вывод», но так и не понял, что это. Высер старпера-эксперта, троллинг или что-то третье?
    • +16
      Очем писалось в басне,
      Не знает даже автор.
      Хотя, мы не уверены,
      Что он у басни есть.
    • +7
      Автор статьи — тролль 80-го левела.
      • +1
        Всего лишь 80-го?
        • +1
          Для левел-апа пора учиться писать по-короче.
  • +4
    Лол, я бы посмотрел на то, как выглядит поддержка оооогромной кучи динамического кода. Точнее, я уже насмотрелся, конечно, но посмотрел бы ещё :D люблю острые ощущения
    • 0
      Я бы еще на производительность посмотрел.
    • +1
      Ага ) Вспоминаю поиск в исходниках на Ruby нужного мне метода. Который, как оказалось, создается динамически :-) И IDE с такими конструкциями ой как не дружит…
      А если все это писал не ты — это покруче чем #define true (random() > 0.5).
  • +1
    Я таких комментариев не встречал ни разу.
    Но думаю что лучше уж будут такие комментарии у говнокодеров, т.к. из них можно хоть понять ход мыслей, понять зачем здесь этот кусок дерьма.
    • 0
      Это позволяет все отрефакторить и удалить портянки.
      Хотя времени убьешь…
  • +2
    Я при написании комментариев руководствуюсь следующим принципом: пойму ли я, что делает код, открой я его месяца через два? От этого и длина комментариев зависит.
    Раньше мне тоже очень нравились конструкции вида «сделать офигенно» и мемуары в комментариях, но сейчас я понимаю, что все это на самом деле не несет в себе никакой полезности, а порой и смысла.
    • 0
      Я при написании комментариев руководствуюсь следующим принципом: пойму ли я, что делает код, открой я его месяца через два?


      «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете» © Стив Макконнелл
  • +4
    По мне так вопрос о комментариях очень второстепенный в статье. Это так для затравки. Читал 1 раз и вскользь т.к. много букв. Не все понял что хотел автор. Замечал противоречия в его рассуждениях, но не стал возвращаться назад чтобы их уточнять, мне это было не интересно было. Автор говорит про модели очень абстратно и неконкретно как будто если он скажет что-то конкретное, то придется отвечать на гору каверзных вопросов и спорить. Вобщем эта статья требует структуризации, конкретных тезисов, укорачивания и избавления от кучи ненужных метаданных иначе ее не захотят понимать в виду объема, неконкретности, расплывчивости формулировок.
    • 0
      и (или) деления. Слишком много тем затронуто.
    • +4
      Далеко ходить не надо
      Лично я предпочел бы разбираться в сжатом, сложном коде небольшого объема, чем в здоровой системе из тысяч файлов с коментами.

      Лучше отдыхать на юге летом, чем служить на севере зимой…
  • +3
    А когда я был студентом, то у меня в начале некоторых ассемблерных листингов стояли три строки хокку по мнемоническим соображениям.
  • +3
    Ухаха, посмотрел бы я на автора, который бы стал разбираться с унаследованным кодом хотя бы мегабайта в два исходников на каком-либо языке с динамической типизацией )) Без Find Usages, без навигации по коду.
  • +5
    Откуда столько шума? Вроде давно аксиома: комментировать надо то, что из кода не явно, а это случается довольно редко. Комментирование для автоматической документации, при генерации шаблона (любая IDE или простой редактор это умеет делать) мозг не грузит и времени не отнимает.

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

    Что касается моделирования, думаю любой опытный программист подходит к этому процессу итеративно, так что никаких проблем со «сверхмоделированием» для них нет.
    • 0
      > Вроде давно аксиома: комментировать надо то, что из кода не явно

      Я бы еще добавил, что однострочный комментарий полезен перед блоком который выполняет некое законченное действие. Например, десяток строчек, который получают значение используемое далее, неплохо снабдить комментарием типа: «Получаем значение X». Тогда, при просмотре кода, не нужно просматривать этот блок вообще — по комментарию будет ясно что здесь «родилось» Х и можно смотреть дальше. Это ускоряет изучение кода и не вынуждает погрязать в несущественных деталях модуля
  • +11
    По-моему у американцев какая-то страсть по пустякам воду лить. прочитал только треть, дальше зевать начал. Какая-то сплошная рефлексия
  • +2
    Ужас, как много букв… смысл статьи, что в комменты нужно писать только самое важное?
  • +8
    Где-то я видел, что коментарий в коде должен отвечать на вопрос «зачем?», но не на вопрос «как?». Последнее должно быть понятно из кода. Моделирование не есть плохо. Нужно лишь, чтобы модель не была вселенски универсальной и не выходила из области задачи.

    Автор упускает огромную группу людей — либюзеров, которые для достижения результата не заморачиваются, а подключают либу мегов на N-цать, зато в которой есть Tuple2 для возвращения двух значений функции. Они не изобретают, они пользуются чужими изобретениями и паттернами. Таких большинство.

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

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

    А изобретателей-«нубов» на самом деле осталось очень мало. Честь им и хвала! Все должны через это пройти.

    P.S. Есть и психологическое объяснение статьи: когда автор был нубом, он работал за идею (интерес). Когда же он повзрослел, он тупо стал работать за деньги. Поэтому все идейные вещи ему стали казаться глупыми: платят не за идею, а за результат, поэтому че напрягаться?
    • –2
      Узнал себя сразу в двух группах по названиям и описаниям, но как-то то, что пишу тесты для геттеров и сеттеров помогает не дублировать и триплировать код, не устраивать кашу и изменения обычно проходят без перелопачивания кода в 10 местах, а если и требуются в 10 местах, то тесты эти места показывают, включая геттеры и сеттеры.
      • 0
        При чрезмерном злоупотреблении рудиментарными тестами наступает момент, когда поддержка самих тестов становится многократно сложнее самого кода. Это когда Вы делаете изменение в одном месте в коде, и перелопачиваете 50 тестов.
        • 0
          До такого не доходило, вернее было что-то похожее, но просто забылне знал, что в тестах тоже не стоит повторять себя :)
          • 0
            Дублирование кода в трех местах требует переписывания.
            Дублирование кода в двух местах требует переписывания, если это не приведет к излишнему усложнению.
  • +8
    Автору статьи незачет за агрессивность, завышенное самомнение и много спорных высказываний.
  • +1
    Если обильно комментировать, достаточно сложно держать комменты в актуальном состоянии. Особенно когда взахлеб пишешь код, не отвлекаясь ни на что.
  • 0
    плюсанул за старательность — это ж сколько времени потрачено на статью!!! Но дочитал только до середины.
  • +2
    Мне кажется, есть золотая середина, когда код получается и кратким, и откомментированным и понятным. Ближе всего, к этому, мне кажется, позиция Макконнелла:
    1. Короткие методы.
    2. Комментарии к публичным методам и их параметрам.
    3. Принцип «если код плохо читаем — его нужно отрефакторить, а не писать комментарии».
    Вот и всё.
    • 0
      2. Комментарии к публичным методам и их параметрам.


      Под публичными здесь нужно понимать не public-методы, а внешний интерфейс системы или модуля. Внутренних интерфейсов, как правило, слишком много для того, чтобы тратить время на поддержание их в чистоте и порядке.
    • 0
      1. Короткие методы.


      У Макконнелла, помнится, было написано наоборот :-) Приводятся штук 10 практик по написанию хороших методов, а потом сказано, что предложенных выше методик вполне достаточно, и требование о длине методов излишне.
      И я с ним согласен.
      • 0
        Я плохо выразился. Коротких не в плане количества строк, а в плане количества логически законченных действий, которые выполняет метод.
  • +2
    Вобщим как итог автор научился кодить лаконичные программы, но в написании статей он — нуб.
    • +3
      Зря вы так про Стива Йегге — парень писал очень правильные вещи в очень правильное время. Статья очень старая и написана так, чтобы подтолкнуть людей. И да, она написана для новичков, для тех из них, кто с одной стороны достаточно интересуется мнениями в профессии, чтобы на них можно было повлиять, а с другой стороны — достаточно способных, чтобы под влиянием статей они изменились к лучшему и росли как профессионалы. Да, Стив перегибает палку, но считайте это художественным приемом :)

      Стив делал правильное дело, и не важно, что умудренные опытом люди смотрят на его тексты снисходительно или скептически — на них такие статьи уже не действуют, да и они им и не предназначены.
      • +1
        Хорошо мыслите :-) Напомнило притчу.
  • 0
    даже несмотря на невзрачность Java как языка (который, по-моему, стал тревожно похож на Pascal)


    Это за что ж автор так Паскаль ненавидит, что он так его тревожит?
  • +4
    Такое ощущение, что 90% тех кто отписался выше прочли только верхнюю треть статьи. Ау, люди, статья про метаданные, не про комментарии в коде!

    Огромное спасибо за перевод, теперь есть куда тыкать нубов.
    • 0
      +1. Статья безумно понравилась. Многие подобные мысли в голове давно крутились.

      Иногда работая чувствуешь что закопался в проблеме, а проблема то с нулевым business-value. Чистой воды украшательства кода, создание стройной модели, выправление affecting/effecting coupling чтобы пониже был, ну и прочая фигня. И честно признаться я подобного рода задачи возводил в абсолют, мол без хорошей архитектуры проект загнётся и порастёт #овном.

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

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

  • +1
    Не понимаю почему люди выше обсуждают в основном комментирование. Автор затронул гораздо более обширную и интересную тему.
    • +2
      Потому-что это портянка текста?
    • 0
      Осмелюсь предположить, что те, кто обсуждает комментирование(и я в том числе), прочитали только начало статьи.
      • +1
        Как и Вы, осилил сначала только половину текста, но после комментария dborovikov решился и дочитал до конца. Статья действительно отличная, есть над чем поразмыслить.
  • +1
    Осилил только половину текста… Не очень понятно почему так много написано. Очччень много повторов и водички.

    Есть труд. Есть результаты труда. Результаты я всегда представляю в виде готового кода и документации на него. В коде описан процесс. В документации — смысл этого процесса и его алгоритмика. Комментарии в коде носят обычно только характер пояснения к документации, т.е. как бы выполняют синхронизирующую роль.
    При таком подходе главное — выбрать описываемый «кубик», т.е. ту минимальную часть труда, которую надо так бюрократизировать. Не описывать каждое присвоение, но и не очень крупный процесс )
    • –1
      При таком подходе главное — выбрать описываемый «кубик», т.е. ту минимальную часть труда, которую надо так бюрократизировать. Не описывать каждое присвоение, но и не очень крупный процесс )

      *doc к функциям/процедурам/методам, если придерживаться правила, что они небольшие? :)
      • –2
        Именно)
        В *doc же можно засунуть математику, графики и прочую обосновательную ерунду. Я как-то обошелся парой строчек текста и четырмя диаграммами, т.к. из них предельно ясно понятно что, зачем и куда. Пояснения должны быть предельно понятным.
        Согласен, что нет ничего хуже такого засилья комментариев, когда разработчик передавая код говорит, что документация абсолютно не потребуется (типа там все есть), т.к. «там все понятно расписано». Начинаешь смотреть, а так как картины в целом еще нет, образуется каша в голове.

        Кстати, автор мог бы упомянуть, что комментарии бывают трех видов:
        — для себя (вида «При изменении С пересчиать KF1»);
        — для других (вида «Блок настройки коммутатора MUX3»);
        — магические (вида «Не трогать! Иначе не работает!»).
        • 0
          По-моему мы о разных *doc говорим. Я о комментариях для генераторов документации phpdoc, javadoc и т. п.
          /**
          * Проверяет, допустимый ли ход.
          * Например, чтобы задать ход e2-e4, напишите isValidMove(5,2,5,4);
          * @author John Doe
          * @param theFromFile Вертикаль, на которой находится фигура (1=a, 8=h)
          * @param theFromRank Горизонталь, на которой находится фигура (1...8)
          * @param theToFile Вертикаль клетки, на которую выполняется ход (1=a, 8=h)
          * @param theToRank Горизонталь клетки, на которую выполняется ход (1...8)
          * @return true, если ход допустим, и false, если недопустим
          */
          boolean isValidMove(int theFromFile, int theFromRank, int theToFile, int theToRank)
          {
          ...
          }
          • +1
            Мы пишем на языках разного назначения, поэтому и непонятки.
            Я занимаюсь разработкой прошивок конечнох устройств и использую VHDL для описаня схемотехники для САПРа…
    • 0
      Результаты — это работающее приложение без багов. А код, документация, диаграмки, и прочие процессуальные экскременты — это факультативно.
  • +3
    Я будто бы снова вернулся в универ на пары педагогики. Эти же потоки воды низвергающиеся из уст умудренного опытом преподавателя. И та же утрата нити повествования уже на десятой секунде. Butthurt засчитан, я нуб. :(
  • 0
    Если вы, как менеджер по персоналу или владелец фирмы, вдруг читаете в чьем-то резюме слова о «5-6 лет опыта разработки», то знайте — их нельзя перевести как “опытный”. Это переводится так: чувствующий свою неуязвимость малолетка, с вероятностью 50 на 50 напишет вам кучу дерьма, в которой потом не разберется ни его команда, ни он сам, и которую он вероятнее всего не один раз будет переделывать. Но все это в порядке вещей — любой разработчик бывает подростком в своей профессиональной жизни.


    Категорически не согласен с подобными высказываниями.
    Здесь очень многое зависит от самоподготовки, и от того, что называть «5-6 лет опыта разработки». Я предпочитаю под этим понимать написание коммерческих приложений. Если же отсчитывать от точки начала программирования вообще… тогда, возможно, автор прав. И то не могу сказать с уверенностью, т.к. у многих программирование начинается с университета, а после выпуска они уже устраиваются на работу. Я шел немного другим путем, и программирование начинал до универа, поэтому мне сложно судить адекватно…

    IMHO.
    • 0
      У меня сейчас семь лет коммерческого программирования, и я понял, что действительно чувствую себя как подросток — море по колено, бросает в крайности, категоричные суждения и т.п. Уже пошло на спад немного, но полтора-два года назад был пик. У Пола Грэма это хакерской натурой называется, но тут более точно ухвачена суть.
  • +3
    О чем пост?
    О том, что со временем люди набираются опыта и начинают писать немного по-другому?
    Передавайте привет Капитану Очевидность.
    • –1
      Ну если так вопросы ставить, то я думаю всё что есть вокруг будет ни о чем, ибо все очевидно после того как познано. Скорее вопрос должен стоять «для чего?» и тут уже всё ясно.
    • 0
      пост о том, что не стоит увлекаться моделированием.
  • –1
    Ух, наконец-то перевод чего-то стоящего и дающего пищу для размышлений. Спасибо переводчику (хоть и не без ляпов).

    Со многим согласен, в некоторых персонажах узнал знакомые свои черты. Но вот это:
    ценой внесения метаданных вы чуть-чуть ухудшаете поддерживаемость, стоимость, гибкость, тестируемость и расширяемость.
    осталось для меня парадоксом. Я-то считал, что все наоборот. Видимо я еще настолько нуб, что не могу ухватить глубину мысли.
    • 0
      Наверное речь идёт о необходимости синхронизировать код, мета- и простые данные.
    • +1
      Речь идёт о предстоящих проблемах при засовывании многообразия жизни в жёсткие рамки однажды придуманной модели.
  • 0
    Хочу поблагодарить автора (переводчика) за интересную статью. Проблема комментариев действительно остра, но еще более остра проблема метаданных. Когда появились программно используемые метаданные (аннотации), думал, что счастье на земле есть :) Теперь начинаю склоняться к тому, что использование десятка различных аннотаций приводит к потери нити управления, в конечном счете запутанность проявляется еще больше. Пример тому JPA-аннотации, Spring-аннотации, когда уже ничего не видно как работает и как вызывается и вообще уже похоже, что пишешь не на Java, а каком-то дивном языке, по которому надо прочитать еще десяток книжек.

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

    Я бы сказал, что структура проекта очень важна + необходимость реализовывать функциональные требования с минимальными издержками. Структура помогает при поддержке проекта, а граммотная архитектура при написании новых функций.
  • +2
    Муж (м) — программер, (я) — филолог.
    М: Сходи за меня на работу, а?..
    Я: Окей, дорогой, буду править ошибки в комментариях твоего кода))
    М: Я не комментирую код. То, что писалось тяжело, должно и читаться тяжело.
    Я: Лев Толстой, наверное, по такому же принципу работал...

    ©bash.org.ru
    • +1
      По-моему, у профессионала что писалось тяжело, должно читаться легко.
  • 0
    Как по мне, комментариев в коде не должно быть. Совсем. Если требуется добавить в код комментарий, этот код нужно переписать. Естественно, документации это не касается.
    • +1
      И меня всегда удивляли люди, которые оскорблялись этой мыслью.
    • 0
      Например, добавление к функции sort комментария о том, какой алгоритм используется — совсем не лишний.
      • 0
        Совсем лишний, потому что этой информации место в документации к методу.
  • 0
    Странно, никогда не встречал кода с комментариями-рассказами и сам таким никогда не страдал. Щас пересмотрел свои старые бейсик-исходники — везде (как и сейчас) нечастые однострочные комментарии, поясняющие назначение блока. Никогда бы и в голову не пришло писать такие «рассказы» в коде. И как выше заметили, у нас нубы скорее вообще не используют комментарии, чем пишут их избыточно
    • 0
      У них видимо школа есть, и это в её традициях…
  • +1
    Коментарий — это повод для рефакторинга. Если вы пишите коментарий, значит код явно не выражает намерение программиста © Фаулер
    Код (а не коментарии) должен рассказывать историю © Бек, Кэнигхем
    • 0
      Исключение составляет код, реализующий сложный алгоритм с сильной математической базой. Его практически невозможно очень сложно понять, пока не прочитаешь сам алгоритм.
      • 0
        да, хотя в последнее время такие алгоритмы большая редкость
  • 0
    Я не знаю зачем вообще нужны комментарии на java. В плюсах бывают моменты, когда нужно записать, что делает оператор, типа такого «for(;P(»\\n"),R-;P("|"))for(e=C;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);", чтобы не забыть самому. А в java нужно сильно постараться, что бы такое сделать.
    • 0
      парсер — лох?
      • 0
        Совсем немного, угловые ковычки лишние… а так это реальный оператор языка си :) причем боянистый, погуглите его :)
    • 0
      Возьмите реализацию того же RSA.
  • 0
    наоборот, Python и Ruby становятся все более популярными, чем Java и C++
  • +1
    По коментариям создалось впечатление, что те кто не понял о чем статья — даже хуже чем нубы. Статья довольно фундаментальная, и даже несмотря на то что дерьмово написана, обсуждает важный вопрос достижения цели в обмен на онанирование на архитектуру, коменты и прочие маразмы которым каждый 5 программист увлеченно занимается и считает себя крутым за это.
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Очень, очень, очень глубоко копает.
    Когда я был мелким, лет 15, мне досталась дискетка с исходниками простеньких игр, а я сам тоже писал простенькие игры. И там был тривиальный тетрис написанный по всем канонам ООП на щщах с исходниками под 200 кб весом. Исходники моего тетриса занимали 3 кб, несколько массивов, несколько функций плюс отрисовка и обработка прерываний ввода. Я полез внутри и в силу неопытности мало что понял, но расхождение в объеме кода меня поразило.
    Поражает и сейчас, хотя я понимаю что 500 классов или 200 таблиц данных это средненький проект.
    Из нубства на правильный путь меня направил императив уменьшения сложности. Похрен на идеалогию, методики, похен на все, я не хочу держать в голове 500 классов, эффективно жонглировать в голове я смогу лишь 5 из них а остальное лишь запутает мои попытки понять что происходит.
    Любые метаданные это внесение нового уровня сложности.
    С другой стороны правильная организация методов и переменных, их правильное наименование — это наше все, это способ заставить код говорить вместо комментариев.

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