Зачем дьявол придумал javadoc
02 May 2010Есть мнение, что хорошая программа должна быть хорошо задокументирована.
Компания SUN даже придумала специальный формат javadoc - “стандарт для документирования классов Java”. В моей практике было совершенно обычным явлением, когда какой-то код не проходил Code Review, потому что в нём у некоторых методов отсутствовали комментарии.
Сегодня я расскажу, почему комментарии - это зло.
Например
Возьмём пример из жизни. Это реальный код, написанный вполне старательным программистом, который не поленился и написал комментарий к своему методу. Довольный собой, но пошёл налить себе чашечку кофе из аппарата, а мы давайте-ка пока посмотрим, что же тут у нас есть.
public class AddressUtil {
/**
* Format string as address, expected input
* format:"EE ; ;Tallinn;Narva mnt;120B;831;10127"
*
* @param flatAddress
* @return Formatted address
*/
public static String toString(String flatAddress) {......}
}
Отлично! У нас есть корректно оформленный комментарий в формате javadoc, из которого специальная программа сможет сгенерировать HTML-документацию. По нему легко можно понять, что (теоретически) делает этот метод.
Где же спрятался дьявол?
Но где же те мелочи, в которых спрятался дьявол? А вот они:
- Очень скоро эта документация устареет, потому что придёт другой девелопер и поменяет код, но забудет поменять документацию. Это может быть даже тот же самый девелопер, потому что пока он стоял в очереди за кофе, ему пришло в голову, что он забыл обработать один редкий случай. Вернувшись, он добавит нужный IF в код, но забудет о том, что у него уже есть javadoc, который необходимо поддерживать.
- В документации не описаны масса случаев: как поведёт себя метод, если на входе придёт null или пустая строка?
Что, если в адресе есть номер дома, но нет номера квартиры (то есть буржуй занял дом целиком)?
Что там за пустой параметр между
EE
иTallinn
? - В документации нет ни слова о том, что этот метод возвращает.
- В документации есть целых три лишних строчки: “*”, “@param flatAddress” и “@return Formatted address”. Только подумайте: они занимают большую часть документации, и они абсолютно бесполезны!
Волшебство
А теперь давайте поиграем в волшебников и превратим несколько цветных кусочков в гирлянду. Сделаем несколько магических пассов. Сим-салябим, Ахалай-махалай, Ляськи-масяськи….
-
Пасс номер 1: Основной текст из комментария
Format string as address
превращаем в название метода:toString
->formatAddress
. -
Пасс номер 2: Описание параметра
expected input, expected: ...
из комментария переносим в юнит-тест. -
Пасс номер 3: (мой любимый) Весь остальной комментарий стираем нахрен. Не жалейте его, он зря появился на свет! Это кодская спарта!
Что у нас получилось в итоге?
public class AddressUtil {
public static String formatAddress(String flatAddress) {......}
}
public class AddressUtilTest {
@Test public void testFormatAddress() {
assertEquals("Narva mnt 120B-831 10127 Tallinn",
AddressUtil.formatAddress("EE ; ;Tallinn;Narva mnt;120B;831;10127"));
}
}
Чем же новый вариант лучше старого?
- Он тупо короче: было 8 строк, стало 4.
- Этот тест никогда не устареет, т.к. он будет запускаться автоматически каждый раз при сборке проекта, и если программист поменяет код, а о методе забудет, это сразу всплывёт.
- Можно описать все редкие случаи: пустые строки, отсутствующие параметры, недопустимые значения и т.д.
Одним словом,
ХОРОШЕЕ НАЗВАНИЕ + ТЕСТЫ = ДОКУМЕНТАЦИЯπ
а точнее, “запускаемая документация” (executable documentation), то есть документация, которую можно не просто читать, но ещё и “запускать”, автоматически проверяя, что она всё ещё адекватна.
Говорят, у Конфуция над кроватью висел плакат:
Convert comments to executable documentation
Послесловие
Боюсь только, что наш доблестный программист, вернувшись с кухни, фокуса не поймёт, ведь он не видел наших волшебных движений. Ему снесёт башню от одного только факта, что его комментарии КТО-ТО НАГЛО ПОТЁР, и он постарается нас найти и уничтожить за такую подрывную деятельность.
А его кофе тем временем остынет. Ну что ж, и то неплохо: ведь кофе, говорят, вреден. Значит, одно хорошее дело мы всё-таки сегодня сделали.