Вам нужна документация (в некоторой форме; не всегда комментарии) для локального понимания кода. Код сам по себе говорит вам, что он делает, если вы прочитали все этого и можете помнить все это. (Подробнее об этом ниже.) Комментарии лучше всего подходят для неформальной или полуформальной документации.
Многие люди говорят, что комментарии - это запах кода, который можно заменить рефакторингом, улучшенными именами и тестами. Хотя это верно для плохих комментариев (которые легион), легко перейти к выводу, что это всегда так, и аллилуйя, больше никаких комментариев. Это возлагает всю нагрузку на локальную документацию - я думаю, ее слишком много - на именование и тестирование.
Документирует контракт каждой функции и, для каждого типа объекта, что он представляет, и любые ограничения на допустимое представление (технически, функция абстракции и инвариант представления ). Используйте исполняемую тестируемую документацию, где это целесообразно (doctests, модульные тесты, утверждения), а также пишите короткие комментарии, дающие суть, где это полезно. (Там, где тесты принимают форму примеров, они неполны; там, где они полны, точные контракты, они могут потребовать столько же усилий, сколько и сам код.) Пишите комментарии верхнего уровня для каждого модуля и каждого проекта; они могут объяснить соглашения, которые делают все ваши другие комментарии (и код) короткими. (Это поддерживает именование как документацию: с установленными соглашениями и местом, где мы можем ожидать, чтобы найти тонкости, мы можем быть более уверены, что имена говорят все, что нам нужно знать.) Более длинные, стилизованные , раздражающе избыточные Javadocs имеют свое применение, но помогли создать обратную реакцию.
(Например, это:
Выполнить n-кратную фробуляцию.
@ param n количество раз, чтобы заморозить
@ param x x-координата центра вспышки
@ param y y-координата центра вспышки
@ param z z-координата центра вспышки
может быть похоже на «Раздувать n раз вокруг центра (x, y, z)». Комментарии не должны быть рутиной, чтобы читать и писать.)
Я не всегда делаю, как я говорю здесь; это зависит от того, насколько я ценю код и кого я ожидаю прочитать. Но изучение того, как писать таким образом, сделало меня лучшим программистом, даже когда он срезал углы.
Вернемся к утверждению, что мы документируем ради локального понимания: что делает эта функция?
def is_even(n): return is_odd(n-1)
Проверяет, является ли целое число четным? Если is_odd()
проверяет, является ли целое число нечетным, тогда да, это работает. Предположим, у нас было это:
def is_odd(n): return is_even(n-1)
Те же рассуждения говорят, что is_odd()
проверяет, является ли целое число нечетным. Разложите их вместе, конечно, и ни один из них не работает, хотя каждый из них работает, если другой работает. Измените его немного, и у нас будет код, который работает, но только для натуральных чисел, и в то же время локально выглядит так, как будто он работает для целых чисел. В микромире это то, на что похоже понимание кодовой базы: отслеживание зависимостей в кругах, чтобы попытаться пересмотреть предположения, которые автор мог бы объяснить в одной или двух строках, если бы они беспокоились. Я ненавижу за счет духовных бездумных кодеров, которые привели меня к этому в течение последних нескольких десятилетий: о, этот метод выглядит так, как будто он имеет побочный эффект, чтобы подавить варпкор ... всегда? Ну, если странные кробункулы обесцвечивают, по крайней мере; они? Лучше проверь весь код обработки crobuncle ... который создаст свои собственные проблемы для понимания. Хорошая документация сокращает эту погрешность указателя O (n) до O (1): например, зная контракт функции и контракты вещей, которые она явно использует, код функции должен иметь смысл без дальнейшего знания системы. (Здесь контракты о том, что is_even()
и is_odd()
работают с натуральными числами, говорят нам, что обе функции должны проверяться на n==0
.)