5/13/2010

Why the devil invented javadoc?

It is believed that a good program should be well documented.

SUN company even creared a special format javadoc - "a standard for documenting classes Java". In fact, it was quite a common case in my experience, when a code did not pass Code Review just because some of its methods lacked comments.

Today I'll tell you why the comments are evil.

Start from example


Consider the real example from live code. This is a real code written quite diligent programmer who was not lazy and wrote a commentary on his method. Pleased with himself, he went to pour himself a cup of coffee from the machine. While he is going to the office kitchen, let's take a look at what we have here.

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) {......}
}


Excellent! We have a correctly designed a format javadoc, from which a special program can generate HTML-documentation. As it is easy to see that (theoretically) makes this method.

Where is the hidden devil?


But where are those little things that hid the devil? And here they are:

  1. Very soon this documentation becomes outdated, because some other developer will come and change the code, but forget to change the documentation. It may even be the same developer, because while he was standing in line for coffee, it occurred to him that he forgot to process one rare case. When he comes back, he adds the desired IF into the code, but forgets that he already has javadoc, which must be maintained.

  2. This documentation does not describe the mass of cases: how the method behaves, if the input comes null or empty string? What if address contains house number, but misses apartment number (ie bourgeois took home a whole)? What's that empty parameter between the "EE" and "Tallinn"?

  3. Documentation doesn't describe what this method returns.

  4. There are three extra lines in the documentation: "*", "@ param flatAddress" and "@ return Formatted address". Just think: they occupy a large part of the documentation, and they are absolutely useless!

It can be summarized in two words: "Comments lies"! That's all. You cannot do anything with this, except the cases when you have a special position for people how review all the documentation periodically. Damn, do you really want to do that?

The Magic


Now let's do a focus-pocus and create The Magic. We make a few magical passes. Sim salyabim, Ahalan-mahalay, Lyaska-masyaski ....


  1. Pass # 1: Everything that is written in red, we turn to the name of the method: toString -> formatAddress.

  2. Pass # 2: Everything that is written in blue, transfer to unit-test.

  3. Pass # 3: (my favorite) The text, written in green, wipe fuckin. Do not spare him, he was born in vain!

What we did in the end?

public class AddressUtil {
public static String formatAddress(String flatAddress) {......}

@Test public void testFormatAddress() {
assertEquals("Narva mnt 120B-831 10127 Tallinn",
AddressUtil.formatAddress(
"EE ; ;Tallinn;Narva mnt;120B;831;10127"));
}

}


What the new version better than the old?

  1. It's just shorter: there are now 4 rows compared to former 8.

  2. This test will never becomes obsolete, because it will run automatically every time you build the project, and if the programmer change the code, and forget about the method, it immediately pops up.

  3. You can describe all the rare cases: the empty string, missing keys, invalid values, etc.



In short,
GOOD TITLE + TESTS = DOCUMENTATION


rather, executable documentation, or documentation that can not only read but also "run", automatically checking that it is still adequate.

It is said that Confucius was a poster over the bed:

Convert comments to executable documentation



Afterword



I'm just afraid that our brave programmer, returning from the kitchen, will not understand the focus, because he had not seen our magical movements. He will get mad only because SOMEONE Nagle has deleted his comments, and he will try to find us and kill for such subversive activities.

... And his coffee gets cool in the meantime. Well, no so bad: after all, coffee, they say, is harmful. So, we did today did one good thing.



Andrei Solntsev

http://funny-java.blogspot.com/

PS. Well, I must admit the documentation is still needed in some cases, for example, when you writing public API, which other people will download and use. This API is hardly going to be changed, so it's possible to maintain the documentation. But you must remember that documentation is not just comments in code - this is a part of you product, which requires resources for creation and maintenance. Tule of thumb: prefer NOT to writing comments. Write them only if it's really unavoidable.

3 комментария:

Unknown комментирует...

If your code is cohesive you probably won't have to change the api or the documentation. There are also many cases where documentation is unavoidable. What if the user doesn't have access to the code? And I'm sure you look at the code for the java api rather than just look at the javadoc.

asolntsev комментирует...

@John Mercier
John, you are right: source code is not always available, and javadoc is still useful for public APIs.

I am talking more about code which is created and used within the same company.

Dimon комментирует...

Вот почему важно делать Code Reviews и писать Javadoc корректно!

Я с вами абсолютно согласен по поводу:

Well documented code + meaningful tests - это практически всё, о чём девелопер может мечтать.

К сожалению, пример Javadoc в статье приведён довольно хилый - это практически "только что сгенерированный стаб", дополненный одной срочкой - в большинстве организаций так его никто бы не написал*.

* По крайней мене я на это надеюсь.
* По крайней мере я такого часто не встречал, а когда встречал, то такой коммит не прошёл бы Code Review.

Поэтому, адресуя отмеченные вами четыре поинта:

1) Одна из вещей на которую ревьюеры смотрят когда делают Code Reviews - это documentation update если надо.

2) То, что эта приведённая в пример Javadoc не описывает ничего - проблема девелопера и ревьюера. Это обязанность девелопера обновить документацию к изменённой функциональности.

Если и девелоперу и ревьюеру на это по барабану, то это уже другая история.

Особенно важно, когда различные команды работают in the same space и которым поневоле приходится использовать API друг друга.

Но и когда всё пишется внутри одной организации, я всё равно не вижу смысле не документировать код по нормальному.

3) См. №2.

4) Не понимаю поинта. Если правильно написать meaningful javadoc, то, поверьте, место, которое оно будет занимать будет волновать вас меньше всего.

В добавок к вышесказанному:

приведённый метод является довольно интуитивно понятный. Интуитивно понимать без докумментации бывает не всегда возможным - даже когда метод именован в соответствии с его функциональностью.

javadoc обязателен.

По поводу тестов - это так же одна из вещей, на которую смотрит ревьювер.

Ну а уж если девелоперы не хотят писать javadoc, а ревьюеры не хотят по нормальному делать обзор комммитов, то я уверен и тесты писаться не будут.