Очень часто, и в книгах, и в Интернет, и (возможно) от начальства, можно слышать про необходимость комментариев. Давайте посмотрим, насколько написание комментариев является необходимым.
Во-первых, чем большее количество разработчиков работают над проектом, тем более необходимо наличие комментариев. Если разработчиков немного, возникает другой фактор - фактор человеческой памяти. Если еще три-четыре месяца спустя написания кода можно прекрасно вспомнить, зачем он нужен, как писался, что и почему он делает - вряд ли это удастся вспомнить спустя несколько лет. Особенно, если ведется интенсивная работа над различными проектами.
С другой стороны, комментарии внутри методов - очень часто излишни. Например, напишем (с использованием псевдокода, подозрительно похожего на 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]