Комментарии 36
У меня такое ощущение, что пост про «наболевшее» не лучший выход, и стоило бы воспользоваться помощью таких замечательных инструментов, как Google Groups. Я намекаю на обсуждение данной проблемы в Ror2Ru (=
Есть так же мнение, что читаемости коду добавляет следование DDD, но к сожалению данная методология только набирает обороты (хотя очень сильно).
Есть так же мнение, что читаемости коду добавляет следование DDD, но к сожалению данная методология только набирает обороты (хотя очень сильно).
Вероятно, Вы правы насчёт «поста о наболевшем», однако, разве не так улучшается мир? Некто пользуется несовершенным инструментом, у него после долгого использования «наболело», он громко заявляет об этом и начинает искать варианты улучшений. И находит. Или другие обращают внимание на проблему и находят.
Я думаю вы представляете себе те сложности, с которыми старые матёрые говнокодеры (некоторым из них, правда нет и 30) с кучей пафоса и сигарой в зубах рассуждают об концепциях старой школы и отвергают даже попытки упоминания о DDD, методах с экран и правилами комментирования. Через 5-10 минут разговор перерастает в дремучий холивар о том, что паттерны — зло и «я все пишу правильно не зная ни одно паттерна уже 100500 лет» (напоминает вопрос о 5% самых умных людей). А потом с этим УГ, которое везде суются в виде говнокода ActiveRecord с кучей логики и остального лапшекода вперемешку с алгоритмами приходится разбираться и что-то ещё там фиксить.
В литературе (Code Complete Second Edition by Steve McConnell, Chapter 32) рекомендуется писать комментарии так:
1. Документация состоит из комментариев в листингах и внешней информации(документации).
2. Стоит писать документы для классов, методов и членов классов.
3. Другой вид(внутренний) документации — сам код. Очень важен хороший стиль программирования, а не только комментарии.
4. Циклы выполняют только 1 функцию, нормальный вариант следует внутри if, а не else,
5. булевы выражения упрощаются доп. булевыми функциями.
6. Полезны резюмирующие комментарии, комментарии цели (писать зачем мы делали то или иное действие)
7. Стоит применять комментарии которые несложно редактировать и поддерживать.
8. Один комментарий на 10 операторов — оптимально.
9. Нужны комментарии отдельных строк (если они сложны для понимания )
10. Обязательно нужны комментарии строк, где ранее была ошибка
11. Стоит избегать комментария в конце строк, кроме случаев объявления переменных, исправления ошибок.
12. Лучше описывать абзацы кода.
13. Комментарий должен отвечать на вопросы как или почему (if (accountFlag == 0))
14. Комментарий может играть роль заголовка или роль пояснения сюрприза(повышения производительности за счёт чего-то).
Вывод. Комментарии — must have. Комментируют метод, выходные переменные, результаты, граничные значения, неоднозначные операторы и их наборы, простую алгоритмическую логику внутри метода. Краткость — сестра таланта. Не нужно писать поэм.
В литературе (Code Complete Second Edition by Steve McConnell, Chapter 32) рекомендуется писать комментарии так:
1. Документация состоит из комментариев в листингах и внешней информации(документации).
2. Стоит писать документы для классов, методов и членов классов.
3. Другой вид(внутренний) документации — сам код. Очень важен хороший стиль программирования, а не только комментарии.
4. Циклы выполняют только 1 функцию, нормальный вариант следует внутри if, а не else,
5. булевы выражения упрощаются доп. булевыми функциями.
6. Полезны резюмирующие комментарии, комментарии цели (писать зачем мы делали то или иное действие)
7. Стоит применять комментарии которые несложно редактировать и поддерживать.
8. Один комментарий на 10 операторов — оптимально.
9. Нужны комментарии отдельных строк (если они сложны для понимания )
10. Обязательно нужны комментарии строк, где ранее была ошибка
11. Стоит избегать комментария в конце строк, кроме случаев объявления переменных, исправления ошибок.
12. Лучше описывать абзацы кода.
13. Комментарий должен отвечать на вопросы как или почему (if (accountFlag == 0))
14. Комментарий может играть роль заголовка или роль пояснения сюрприза(повышения производительности за счёт чего-то).
Вывод. Комментарии — must have. Комментируют метод, выходные переменные, результаты, граничные значения, неоднозначные операторы и их наборы, простую алгоритмическую логику внутри метода. Краткость — сестра таланта. Не нужно писать поэм.
Я хоть и старый матерый говнокодер, но паттерны и DDD использую, методы и функции короткие, *doc не ленюсь писать (хотя бы чтобы IDE подсказки адекватные давала), тесты пишу (обычно до кода) и т. п. Единственное не понимаю, что плохого в ActiveRecord с кучей логики, если уж начали его использовать (мне больше DataMapper & co нравится, но частенько альтернативы нет). Не, можно, конечно, на каждый класс типа User с персистентным состоянием и методами для этого вводить класс типа UserHandler без состояния (или временным) и инжектить туда User, но нужно ли?
Всё, что Вы перечислили — прекрасно. Я срочно в гугл искать эту великую книгу.
Комментирование само по себе вроде и хорошо и правильно, но помимо всего требует неимоверной дисциплины от всей команды.
Пример: написали метод, красиво добавили ему комментариев, и все бы хорошо. Но прошло время, кто-то в процессе рефакторинга или просто прикручивая новую фичу, изменил метод, но забыл поправить комментарий.
Что мы в итоге получаем: точно не лгущий код (код не умеет лгать), но лгущий комментарий, использование которого может только проблем прибавить, нежели дать выгоду.
Пример: написали метод, красиво добавили ему комментариев, и все бы хорошо. Но прошло время, кто-то в процессе рефакторинга или просто прикручивая новую фичу, изменил метод, но забыл поправить комментарий.
Что мы в итоге получаем: точно не лгущий код (код не умеет лгать), но лгущий комментарий, использование которого может только проблем прибавить, нежели дать выгоду.
Но прошло время, кто-то в процессе рефакторинга или просто прикручивая новую фичу, изменил метод, но забыл поправить комментарий.
Нет, такой сценарий почти нереален, если делается Code Review. Коммит просто будет отправлен на доработку. Само собой, мы предполагаем наличие адекватного review'ера, остальные случаи рассматривать надо совсем отдельно.
Да ладно, даже если предположить, что у нас идеальный ревьюер, который никогда не делает глупых ошибков (хотя все люди их делают), то может легко остаться какой-нибудь комментарий в заголовке модуля, где упоминается функционал, или в другом методе, который пользуется этим методом — он просто не попадет в контекст ревью в тако случае
Code review — это отдельно взятая ситуация. Но не всегда она имеет место быть. Как и наличие адекватного review'ра. Review'ер может быть адекватным, но иметь какой-то уровень доверия к тому или иному разработчику, чтобы проверять документацию. Ну в общем, допущений в реальной жизни слишком много, ИМХО.
Очень даже реален :) В code-review в основном читают только те строчки, которые поменялись. Бывает что-то вокруг, чтобы понять контекст. И очень редко раскрывают спрятанные блоки (обычно прячется всё, что за функциями, а значит и шапка-комментарий тоже). И получается, если комментарий не правили, то он не подсветится и скорее всего его и не посмотрят.
Если так принято делать в команде — то вероятность ревьюером это забыть такая же, как и не заметить ошибку в коде.
Не знаю как где, но на моей практике код ревьювят не для того, чтобы найти ошибки. CI, юнит тесты и QA делают это в разы эффективнее.
Ревьювят в целом для трёх вещей:
— попридираться к пробелам, отступам и именам переменных. Т.е. стиль кода, читаемость.
— убедиться, что решение было сделано правильно, а не воткнуто костылём. Т.е. архитектура, технический долг.
— потроллить автора вопросами «а что если?». Т.е. ЧСВ и поиск исключительных ситуаций.
Первое и второе нигде, кроме как во время ревью не сделать. А третье, это не совсем тот поиск ошибок, который делает CI и юнит тесты, т.е. не поиск регрессий, и даже не проверка, что фикс действительно работает, а больше тренировка мозга программиста, чтобы привыкал думать.
Ревьювят в целом для трёх вещей:
— попридираться к пробелам, отступам и именам переменных. Т.е. стиль кода, читаемость.
— убедиться, что решение было сделано правильно, а не воткнуто костылём. Т.е. архитектура, технический долг.
— потроллить автора вопросами «а что если?». Т.е. ЧСВ и поиск исключительных ситуаций.
Первое и второе нигде, кроме как во время ревью не сделать. А третье, это не совсем тот поиск ошибок, который делает CI и юнит тесты, т.е. не поиск регрессий, и даже не проверка, что фикс действительно работает, а больше тренировка мозга программиста, чтобы привыкал думать.
… что lists — это на самом не lists, а оставшееся от прошлой команды название и модель эта теперь везде в тестах называется Things
Начнем с того, что переименуем везде lists в things — вот и начали рефакторинг в сторону упрощения кода. И дальше поехали, упрощать, отделять и абстрагировать :)
На меня в этом плане серьезно повлиял TDD — вот уж где пришлось овладеть принципом «low cohesion, high coupling». Как только встает задача «протестировать одну фичу из всей этой макаронины» — сразу начинаешь все разделять на разные сущности, код логически становится гораздо проще. Меньше shared state, больше явного взаимодействия.
Не хотел сначала читать статью, т.к. она про руби, а руби я не знаю, но прочитал и не разочарован — ваши советы можно применить к любой технологии!
Описывайте то, как работает этот код. Обязательно, хоть и кратко, в начале каждого файла, содержащего класс, описывайте, что он реализует. Перед методами класса кратко описывайте, что метод получает и что должен создать в конце своей работы, коротко описывайте цепочку, по которой пройдут данные. Так же в файлах-модулях. Комментируйте вычисляемые автоматически значения и назначения создаваемых миграциями полей. В случае длинной цепочки вызовов функций (длиннее трёх) — описывайте цепочку, что вызывает что, хотя бы просто последовательность.
Вместо комментариев гораздо эффективнее писать тесты. Тест сразу даёт возможные входные и выходные значения, а также способы применения данной функции\метода\класса\вьюхи. Поддерживать свой\чужой код с тестами не составляет больших проблем. Речь, конечно, не идёт о говнокоде и говнокоде в тестах. Его поддерживать проблема при любых раскладах.
Я бы озаглавил статью: «Поскольку я всё ещё не пишу тесты, я снова комментирую код приложений на Ruby/Rails» :) Без обид.
Возьмите документацию по Qt и представите как бы она выглядела в виде тестов. Стало бы вам проще разобраться с нуля в библиотеке?
1. Пример прекрасной документации библиотеки Rspec, написанной исключительно на тестах: www.relishapp.com/rspec/rspec-expectations/docs. Вообще, покопайтесь на Relish — там вся документация построена на тестах.
2. Когда вы пишете публичное API неважно веб-сервиса или библиотеки типа QT, то да, конечно, оно должно быть хорошо задокументировано. Но речь идёт о документации кода, который живёт и постоянно меняется. Речь идёт о документировании методов, которые пишет внутренний разработчик, который, априори, должен разбираться как тут всё устроено. Тесты для этой цели подходят прекрасно, иногда гораздо лучше комментариев, ибо ты видишь живой код, видишь, как он применяется и как он работает, с какими данными на входе и с какими на выходе.
2. Когда вы пишете публичное API неважно веб-сервиса или библиотеки типа QT, то да, конечно, оно должно быть хорошо задокументировано. Но речь идёт о документации кода, который живёт и постоянно меняется. Речь идёт о документировании методов, которые пишет внутренний разработчик, который, априори, должен разбираться как тут всё устроено. Тесты для этой цели подходят прекрасно, иногда гораздо лучше комментариев, ибо ты видишь живой код, видишь, как он применяется и как он работает, с какими данными на входе и с какими на выходе.
«Поскольку я всё ещё не пишу тесты, я снова комментирую код приложений на Ruby/Rails» :) Без обид.
А я взял и не обиделся. Дело в том, что тесты я пишу, но тесты не могут взять на себя функцию документирования кода, находящегося в процессе эволюции, т.к. тоже постоянно изменяются. Я предлагаю, кроме комментирования «что должен делать код» и «как код должен делать фичу N», взять за привычку документировать процессы, относящиеся к процессу (простите за тавтологию) разработки. А в целом, я согласен, ближе всего к тому, что я хочу реализовать сейчас находится Cucumber с его сценариями.
P.S. Перечитал и понял, что как-то неясно выразился. Постараюсь в будущем развить концепцию своих идей и изложить её яснее :)
Я не люблю test_unit, но даже тесты, написанные и его помощью дают прекрасное представление о том, что делает код. Пример: github.com/rails/rails/blob/master/activesupport/test/number_helper_test.rb
Речь, конечно же, о коде, который находится в эволюции и постоянно изменяется.
Речь, конечно же, о коде, который находится в эволюции и постоянно изменяется.
В последнее время часто встречаю утверждения, что комментарии и тесты взаимозаменяемы. В некоторых случаях это так, в некоторых нет. Область применения комментариев гораздо шире, чем описание аргументов и результата. В то же время идеальный тест следует алгоритму «подготовить аргументы (состояние) -> выполнить действие -> проверить результат (состояние)». Тест не скажет о том, почему был выбран конкретный способ решения, какие у него могут быть побочные эффекты, какие существуют альтернативы. А если приходится менять незнакомый код, то подобные вещи важны. Что не отменяет важности тестов.
Добавив комментарии, вам понадобится подерживать и их, помимо кода.
или слишком сложно (perl-style, однострочные цепочки функций длиной более 5-ти функций подряд)
perl-style
perl-style 7-летней давности perldoc.perl.org/5.8.8/perlstyle.html
perl-style сейчас perldoc.perl.org/perlstyle.html
не вижу там ничего такого.
НЛО прилетело и опубликовало эту надпись здесь
Мне почему-то кажется, что комментариями и документацией вы пытаетесь подменить коммуникацию между людьми.
Если новичка кто-то кинул в проект не объяснив «как тут принято» — это не проблема документации.
Если новичок сделал очевидно типовую задачу так, «как пришло в голову», а не спросил у коллег — так он и документацию читать не будет.
Я понимаю, что отсутствие доков вовсе — это крайность, но вы тут описываете другую крайность. И за псевдо-экономию времени новичка вы будете платить реальными часами всех участников проекта. Конечно, если в проекте, условно, 3 человека и в среднем один человек в месяц «ротируется», то о документации стоит задуматься, но в этом случае документация — не основная проблема :)
Если новичка кто-то кинул в проект не объяснив «как тут принято» — это не проблема документации.
Если новичок сделал очевидно типовую задачу так, «как пришло в голову», а не спросил у коллег — так он и документацию читать не будет.
Я понимаю, что отсутствие доков вовсе — это крайность, но вы тут описываете другую крайность. И за псевдо-экономию времени новичка вы будете платить реальными часами всех участников проекта. Конечно, если в проекте, условно, 3 человека и в среднем один человек в месяц «ротируется», то о документации стоит задуматься, но в этом случае документация — не основная проблема :)
Комментарии и документация — это часть коммуникаций.
Есть такая штука: communication bandwidth. Безусловно, комментарии — это часть коммуникаций. Но пресловутый bandwidth у них в разы меньше.
Ожидал увидеть пример хорошо написанного кода, требующего комментарий, а увидел пример обычного плохого.
1. модель не переименована
2. коллбэков следует избегать
3. обращениям к внешним интерфейсам место в контроллерах
Плюс хорошее именование функций, переменных, и вопрос о комментировании пропадает сам собой.
Комментарии порой нужны, но пример для этого лучше привести другой.
1. модель не переименована
2. коллбэков следует избегать
3. обращениям к внешним интерфейсам место в контроллерах
Плюс хорошее именование функций, переменных, и вопрос о комментировании пропадает сам собой.
Комментарии порой нужны, но пример для этого лучше привести другой.
А вот такая ситуация: матерый быдлокодер (возможно с командой) ваяет проект (не веб-студия а, допустим, предприятие). Начинает борзеть (забивать на просьбы пользователей, требовать выше ЗП, отказываться внедрять доп. фичи и т.п.). Умный начальник решает — «давай-ка я введу в бригаду пару новичков из института — поубавить спесь с разрабов, да уменьшить зависимость от существующих работников».
Приходит новичок, а там… Ни единого комментария.
Приходит новичок, а там… Ни единого комментария.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Почему я снова комментирую код приложений на Ruby/Rails