Очень часто, и в книгах, и в Интернет, и (возможно) от начальства, можно слышать про необходимость комментариев. Давайте посмотрим, насколько написание комментариев является необходимым.
Во-первых, чем большее количество разработчиков работают над проектом, тем более необходимо наличие комментариев. Если разработчиков немного, возникает другой фактор - фактор человеческой памяти. Если еще три-четыре месяца спустя написания кода можно прекрасно вспомнить, зачем он нужен, как писался, что и почему он делает - вряд ли это удастся вспомнить спустя несколько лет. Особенно, если ведется интенсивная работа над различными проектами.
С другой стороны, комментарии внутри методов - очень часто излишни. Например, напишем (с использованием псевдокода, подозрительно похожего на Java) небольшой метод для магазина по торговле электронными товарами:
[geshi lang=Java]
public class ElectronicStore {
/**
* Приобретение электронного товара
* @param buyerId покупатель товара
* @param itemId идентификатор товара
* @return true, если покупка была успешна
*/
public final boolean buyItem(int buyerId, int itemId) throws SQLException {
// Проверим на валидность покупателя товара:
String sql = "SELECT * FROM accounts WHERE userid = ?"; // выборка из таблицы пользователей
PreparedStatement stmt = conn.prepareStatement(sql); // готовим запрос
stmt.setInt(1, buyerId); // userid = buyerId
ResultSet res = stmt.executeQuery(); // Что у нас получилось?
if (res.next()) { // мы получили какие-то данные
String sql2 = "SELECT * FROM items WHERE itemid = ?"; // выборка из таблицы товаров
PreparedStatement stmt2 = conn.prepareStatement(sql2); // создали
stmt2.setInt(1, itemId); // itemid = itemId
ResultSet res2 = stmt2.executeQuery(); // Что у нас получилось?
if (res2.next()) { // мы получили какие-то данные
float itemPrice = res2.getFloat(2); // сколько стоит товар
float userMoney = res.getFloat(2); // сколько денег на счету
if (userMoney >= itemPrice) {
String sql3 = "UPDATE accounts SET money = money - ?"; // запрос на снятие денег
String sql4 = "INSERT INTO orders VALUES(?, ?, NOW())"; // запрос на запись в лог
//...
return true;
}
}
}
}
}
[/geshi]
Закроем глаза на то, что написан пример не вполне так, как обычно пишут на Java. Закроем глаза на то, что не используются транзакции. Закроем глаза на SQLException. Казалось бы - откомментирована буквально каждая строчка кода. Пробежавшись по исходникам, вроде бы все также становится ясно. Правда же? Стоп-стоп-стоп! Что же все-таки не так в этом коде? В этом коде "не так" то, что он нуждается в комментировании.
Грамотно написанный код может и должен быть понятен безо всяких комментариев. Например, разве здесь нужны комментарии?
[geshi lang=Java]
window.setTitle("Hello world");
window.moveTo(100, 100);
window.setSize(200, 200);
[/geshi]
[geshi lang=Java]
/**
* Приобретение электронного товара
* @param buyerId покупатель товара
* @param itemId идентификатор товара
* @return true, если покупка была успешна
* @throws ElectronicStoreException в случае, если приобрести товар невозможно
*/
public final boolean buyItem(int buyerId, int itemId) throws ElectronicStoreException {
UserAccount user = loadUser(buyerId);
ElectronicItem item = loadItem(itemId);
if (user.hasEnoughMoney(item.getPrice()) {
createItemOrder(buyerId, itemId);
// ...
}
return false;
}[/geshi]
Имеем: код написан на почти нормальном английском языке, в излишних комментариях не нуждается. javadoc для методов loadUser, loadItem, hasEnoughMoney, createItemOrder,конечно же, необходим. Но не надо там писать трактаты, вполне достаточно написать какие-либо особенности реализации метода:
[geshi lang=Java]
/**
* Загрузка пользователя из БД
* @param userId уникальный идентификатор пользователя
* @throws ElectronicStoreException в случае, когда пользователь не найден
*/
protected final UserAccount loadUser(int userId) throws ElectronicStoreException {
// ...
}[/geshi]
Такие небольшие методы "документируют" сами себя. Если метод состоит из десятка строк, и этот десяток строк написан на английском языке, и при этом не содержит или почти не содержит ветвлений, документировать его, на мой взгляд, необязательно, хотя и допустимо. Но... если недокументированный код способен понять даже не-программист, лишь взглянув на него, зачем писать комментарии?..
Комментировать или не комментировать? Решать, разумеется, вам. Лично я считаю, что в целях недопущения хаоса и в целях экономии времени, следует придерживаться таких правил:
- Базовая часть комментария к методу или переменной должен быть однострочной. Если в одну строчку описание не умещается, возможно, метод просто слишком громоздкий?
- Обязательно должны присутствовать какие-либо особые требования или примечания. Например, что будет, если передать в метод null.
- Весьма желательно, чтобы в комментарии к методу присутствовал список Exception'ов, которые могут возникнуть во время работы метода, и в каких случаях они возникают
- Хорошо, когда подобные комментарии есть у всех public методов.
- Очень хорошо, когда подобные комментарии есть у всех public методов, и у всех полей класса
- Отлично, если подобный комментарий присутсвует у всех protected, public и package local методов.
- Обязательно рядом с пометками TODO, должен находиться подробный комментарий, с целью описания необходимости реализации пункта TODO.
- Весьма желательно, чтобы внутренние комментарии (если они необходимы), были оформлены в одном стиле. Спасибо Росту Flash-Ripper'у за этот пункт. Например, так (перед блоком, к которому относится комментарий):
[geshi lang=Java] // сделать раз doOne(); // сделать два doTwo();[/geshi]
или, наоборот, так (после строки кода, к которой относится комментарий):[geshi lang=Java] doOne(); // сделать раз doTwo(); // сделать два [/geshi]