Blog-Archiv

Dienstag, 16. April 2019

JavaDoc Is Not Deprecated

Modern object-oriented source code doesn't have a big percentage of comments and documentation any more. Recently I measured a project to have just one percent, and these few were texts copied from the specification. So developers do not explain any more why they did it in the way they did it.

I remember times when 25 percent comments in source code was a quality criterion. I'm going to think about the reasons for it in this Blog.

From Domain-Driven Design, Chapter 11, The Flagged Core, p420 A team that uses the code as the sole repository of the model might use comments, maybe structured as JavaDoc, or might use some tool in its development environment. The particular technique doesn't matter, as long as a developer can effortlessly see what is in and what is out of the core domain.

Why Should We Comment?

We should comment because source code is hard to read. It is a translation of some business reality into the jargon of a machine, done through assignments, conditions, loops, and function calls.

I remember a programming test that exposed a 5-line loop where you had to find out what it does, and lots of testees failed. A consequence of what I call hard to read.

The concept behind an implementation gets clear only when you read and understand all involved source code. Developers that have to fix our bugs spend most of their time doing exactly that. We should write comments because the decisions we made during the implementation will not be visible out of the source code.

I remember a unit test, asserted to fail, inside it had a long list of parameters being passed, one of them being wrong, and I had to find out which one is the wrong parameter to be tested. What about marking the one with a comment? Would save a lot of time for readers.

Sustainability is a good reason to write comments. Have mercy with those that come after you. Tell them the harsh truth. Don't scorch the earth. Overcoming the sentence "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live", we could state a little more positively "Always code as if the girl who ends up maintaining your code is the good looking one living around the corner":-)

Think of global languages full of side effects like CSS. Finding the layout bug and fixing it took you half a day, just for removing one rule. Ok, we can't comment rules that are not there any more, but we should let know others what the problem was, and how it was fixed, right at the place where the bogus rule was. No way around writing a comment (with an issue-number please).

Finally we should write comments for ourselves. People that believe they will remember their code forever are mostly inexperienced newcomers. You need to make it easily readable also for yourself.

Isn't Object-Oriented Code Self-Explanatory?

Surely for the author in the moment it is written. But for others, or viewed a year later, maybe not.

Martin Fowler called comments a sweet smell, because they are always there when something wasn't worked out neatly, with the comment carrying the excuse. But, to be honest, which developer has the time to work out something perfectly? And, in case it is actually an excuse, would we be better off not having that excuse?

Self-explanatory field-, method- and class-names can't always express everything that is important for the caller. In most cases they would simply be too long when telling everything that happens within them, and using abbreviations instead of long names would make it even worse. That's what JavaDoc was made for.

The core problem is that technical complexity is so overwhelming sometimes that we run out of words to describe it precisely.

Can We Tackle Complexity by Header Comments?

Yes we can. The price though is duplication of semantic, from code into human readable text.

Source code is a big tree (or graph) of classes and methods calling other classes and methods. In case you need to call a public method of another class that was named process() or the like, you would have to find out what it does by reading all the source code below it.
Now imagine that this topmost method has some JavaDoc attached. If you configured your IDE to display JavaDoc on mouse-over, you could dare to trust that quick information. Takes half a minute to understand, versus one hour studying private sub-calls. Promotion of encapsulation. I believe that Java wouldn't have become so popular if its libraries weren't javadoc'ed sufficiently already in 1995.

Comments can tackle complexity also in a psychological way. If you write the header comment before you implement the method, you may find out that your first plan about it will not work. Designing first saves you the time you will need to debug fast-built but failing implementations. You start to design while you think about the real intent, especially when you describe responsibilities.

An even higher level is writing the design into the issue you are working on. In that case a colleague could review it and give valuable hints. You could finally copy the ready-made concept into a JavaDoc class header.

Header and Inline Comments

Header comments are on public classes, methods and constant fields. Inline comments are inside classes and methods, explaining details.

  1. We should explain the concepts we followed during implementation. There is no better place than header comments for documenting concepts.

  2. In inline comments you should not comment what you are doing, but why you are doing it. This is what readers will ask: Why is this method invocation here and not at the end of the block?

How to JavaDoc

Remember CRC cards, one of the earliest OO software design methods: Class-Responsibility-Collaboration. Put the responsibility and collaboration of the class into its header comment!

Following is a piece of code that I would consider to be documented sufficiently.

/**
 * Responsibility of this class is to show that JavaDoc is not useless.
 * Context is a project with thousands of classes with very general names.
 *
 * @author fritzthecat 2019-04-16
 */
public class JavaDocIsNotDeprecated
{
    /** Publics always should be javadoc'ed. */
    public static final String AGREE = "More comments!";

    private int count;  // privates should have good names to be self-explanatory

    /**
     * Save our time by documenting!
     * @param comment the text to write as comment to stdout.
     * @return the instance for more comments.
     */
    public JavaDocIsNotDeprecated writeComment(String comment) {
        System.out.println(comment);  // use out because err is not platform-independent
        return this;
    }

}

All publics should be documented, because they are visible to the outer world. Protected also need to be, although you should avoid protected fields (results in weak encapsulation). Inline comments explain reasons and intents.

Resume

Comments and documentation is considered to be useless extra work. Useless because words can not describe the complexity we saw. Extra work because it is duplication of code that doesn't auto-update itself.

It was also the guy with the "sweet smell" that told us to "write code for humans, not computers". So, can we find method names that will inform humans about what is going on? Or would we like to express it in natural language in a JavaDoc comment?




Keine Kommentare: