Предыдущая глава: Функции
Наша цель использования комментариев заключается в том, что мы не можем достаточно выразить себя с помощью кода. Но комментарии всегда неудачны. Потому что мы не знаем, как выразить себя без них.
Итак, если вы оказались в ситуации, когда вам нужно написать комментарий, вернитесь к коду и попытайтесь выразить себя в коде.
Код меняется и развивается. Куски его перемещаются отсюда туда. Но комментарии не всегда могут следовать за ними. И комментарии отделяются от кода, который они описывают. Например:
MockRequest request; private final String HTTP_DATE_REGEXP = "[SMTWF][a-z]{2}\\,\\s[0-9]{2}\\s[JFMASOND][a-z]{2}\\s"+ "[0-9]{4}\\s[0-9]{2}\\:[0-9]{2}\\:[0-9]{2}\\sGMT"; private Response response; private FitNesseContext context; private FileResponder responder; private Locale saveLocale; // Example: "Tue, 02 Apr 2003 22:18:49 GMT"
Обычно комментарий описывает константу HTTP_DATE_REGEXP. Но добавлены другие переменные экземпляра. И комментарий не обновился.
Одной из наиболее распространенных причин написания комментариев является плохой код. Мы знаем, что код беспорядок. И мы хотим добавить комментарии, чтобы описать себя. Но это не очень хороший способ. Четкий и выразительный код с небольшим количеством комментариев лучше, чем сложный код с большим количеством комментариев.
Конечно, кода всегда недостаточно для объяснения самих себя. Но есть способ. Посмотрите на эти два кода ниже, что бы вы хотели увидеть?:
// Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
or
if (employee.isEligibleForFullBenefits())
Хорошие комментарии
Некоторые комментарии необходимы и полезны.
Например, заявления об авторских правах и авторстве необходимы и разумны для размещения в комментарии в начале каждого исходного файла:
// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved. // Released under the terms of the GNU General Public License version 2 or later.
Иногда мы добавляем комментарии //TODO для заметок:
//TODO-MdM these are not needed // We expect this to go away when we do the checkout model protected VersionInfo makeVersion() throws Exception { return null; }
Выглядит как хороший комментарий, но все же комментарии TODO не являются оправданием для того, чтобы оставлять плохой код в системе.
Если вы пишете общедоступный API, вам следует написать для него хорошую документацию по Java. Но Javadocs может вводить в заблуждение и быть нечестным, как и любой другой вид комментариев.
Плохие комментарии
Если вы решили написать комментарий, то потратьте свое время и напишите лучший комментарий. Посмотрите на этот пример, автор не уделил особого внимания своему бормотанию:
public void loadProperties() { try { String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); } catch (IOException e) { // No properties files means all defaults are loaded } }
Что означает этот комментарий? Вероятно, если мы получим IOException, то файлов свойств не было и загружаются все значения по умолчанию. Но как ? Были ли они загружены до вызова loadProperties.load? Или loadProperties.load перехватил исключение, загрузил значения по умолчанию, а затем передал исключение, чтобы мы его игнорировали? Или loadProperties.load загрузил все значения по умолчанию, прежде чем пытаться загрузить файл? Или — это самый страшный сценарий — он написал этот комментарий, а он вернулся и загрузил настройки по умолчанию.
См. следующий пример кода, чтение — пустая трата времени:
// Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached. public synchronized void waitForClose(final long timeoutMillis) throws Exception { if (!closed) { wait(timeoutMillis); if (!closed) throw new Exception("MockResponseSender could not be closed"); } }
Код достаточно информативен. Комментарии не требуются.
Как насчет следующих комментариев Javadoc? Они ничего не объясняют.
/** The name. */ private String name; /** The version. */ private String version; /** The licenceName. */ private String licenceName; /** The version. */ private String info;
Смотри внимательно. Вы распознаете ошибку копирования-вставки? Если авторы не обращают внимания на то, когда пишутся (или вставляются) комментарии, почему читатели должны получать от них выгоду?
Посмотрите на следующий код. Возможно, автор сначала написал комментарий, а затем код:
// does the module from the global list <mod> depend on the // subsystem we are part of? if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))
Автор должен был провести рефакторинг кода, чтобы комментарий можно было удалить.
ArrayList moduleDependees = smodule.getDependSubsystems(); String ourSubSystem = subSysMod.getSubSystem(); if (moduleDependees.contains(ourSubSystem))
Иногда программисты пишут комментарии к закрывающим фигурным скобкам. Это может иметь смысл, если ваш код слишком длинный. Но вместо этого попытайтесь сократить свою функцию.
public class wc { public static void main(String[] args) { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)) ; String line; int lineCount = 0; int charCount = 0; int wordCount = 0; try { while ((line = in.readLine()) != null) { lineCount++; charCount += line.length(); String words[] = line.split("\\W"); wordCount += words.length; } //while System.out.println("wordCount = " + wordCount); System.out.println("lineCount = " + lineCount); System.out.println("charCount = " + charCount); } // try catch (IOException e) { System.err.println("Error:" + e.getMessage()); } //catch } //main }
Не делайте закомментированный код.
InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));
Когда вы видите этот закомментированный код, что вы думаете? Есть ли у вас мужество, чтобы удалить его? Вы подумаете, что это важно для удаления. В старые времена код с комментариями был полезен. Но теперь у нас есть хорошие системы управления исходным кодом. Эти системы запомнят код для нас. Просто удалите его.
«Не комментируйте плохой код — перепишите его»
Брайан В. Керниган