Code commenting? Try Business Commenting.

Jeff has a good post here about code comments and that they shouldn’t be used as crutches:

Coding Horror: Coding Without Comments

I agree with the article, but one thing I rarely hear mentioned is that it’s often more interesting to comment the business justification than it is to comment the code. Jeff goes some way towards suggesting this when he says to comment the “why”, but for many people that translates to “Why did I write the code this way?”.

I often find that code I’m maintaining is missing comments regarding the business logic. Rather than “Why is the code designed like this?”, something like “Why is the business process designed like this?”

This becomes most useful when you look at unfamiliar code (your own, probably) and decide that the easily-digestible code is nevertheless doing something you are sure is silly, and you change it. Big mistake.

Example of a code architecture comment:

   1: // We cache these values because they only change once per
   2: // week or so.


   1: // We lazy-load these properties because they're rarely used
   2: // and they chew up a decent amount of RAM.


Example of a business architecture comment:

   1: // We copy the lab owner on this mail because even though
   2: // they don't own this resource, they wanted to be aware
   3: // of changes. See bug 54321 for request and history.


   1: // This used to delete items older than 30 days, but
   2: // bug #65432 requested that an exception be made for
   3: // items that are of type X.


All are useful, but I find the second type are rarely used. They become more valuable as the code ages.



Comments (16)

  1. Excellent, excellent, excellent!

    (and no, this is not a SPAM comment 😉

    (wouldn’t a SPAM comment say it’s not a SPAM comment?)

    (and no, this is really no SPAM comment, the post is excellent and I often wish there was a business comment in the code I read to know why a developer wrote code in such a – sometimes complicated – way, so I don’t violate a business requirement when refactoring or "fixing" the code.)



  2. Anand V says:

    I do not have much experience in writing system level code, but I agree to Jeff’s post that determining whats happening from it is really difficult.

    On the other hand, when you are writing business applications, you would really want your code and test to do the talking. The code should be written as close to the Domain and the Test should act as a good specification such that you should never require any comments.

    Fine examples of this kind of effort are Domain Driven Design, Behavior Driven Development. An example API being jmock

  3. Myles Braithwaite says:

    I am going to start write comments like that. Thanks

  4. ChrisJ says:

    I use a bit of both, but never really thought much about it. Now that it’s spelled out this way, it makes a lot of sense.

    Big up, mate!

  5. Brad says:

    Folks — business logic is described in specifications. Do you have documented specifications for software you write?

  6. sumati says:

    nice list, thanks for sharing.

  7. Nown O'Urbusiness says:

    It looks like you’re putting data into the code. I separate data from processing logics.

    There are only so many working at companies where this "business commenting" would even make sense. I work with a completely general platform that doesn’t have special-cases at all.

    Besides, your "business comments" are as much "code architecture comments" because they do comment the code and how it works, implicitly. They, too, will need to be updated when the code changes.

    I call shenanigans and whine over nothing.

  8. Dave says:

    @Anand: "On the other hand, when you are writing business applications, you would really want your code and test to do the talking."

    If you’re looking at the code, you don’t want to see something like "includeLabOwnerEmailPerBug1234()". Use a comment: without it it won’t be clear why you’re doing something.

    Tests examine what’s happening. Not why. And yes, you could name your test "ensureLabOwnerEmailedAsPerBug1234()", and if your test methodology includes source-level references from the code under tests to the tests perhaps that’s enough. I don’t think it is, but at that point it’s largely a matter of preference.

  9. Mark says:

    Sometimes it is important to say why a bit of code was written this way. I can’t tell from your ambiguous wording whether you were being dismissive of this practice or not, but certainly some readers will read it that way.

    If my code is:

    if ( $pid = fork ) {

    I do want a comment there saying that I DID mean to say ‘=’ and not ‘==’ so that maintenance programmers, including myself a year later, get a hint that the code as written is not buggy (because, without a comment, it does look like a bug to people who don’t know what is going on).

    Your suggestion of commenting business processes is a good one. But your sloppy writing risks leading people to think you are advocating throwing out the baby with the bath water.

  10. AviP says:

    @Mark: I’m not sure what baby I’m throwing out with which bathwater. As I said, I think both types of comments are valuable.

    @Brad: Specifications are great, but my experience has shown that they’re generally not available at all or not up to date with the code. I wish it wasn’t that way, but when it is, I rather have comments like that to protect the code from what seem like innocent changes.

    At the end, this isn’t a right/wrong thing. It works for me in my environment; it may not work for you in yours…

  11. .. and the replies in that thread make a lot of sense too!

  12. Rob says:

    There’s always a way to redesign the entire program to make these special cases go away. So, in theory, comments are almost unnecessary. However, in practice, the better designs may not become evident until years later. By that time, it’s easier to use the easy fix and write a comment.

    Also, having a document that details the specification is great, but be honest, would you use it? If you were trying to track down a bug and found a line of code that looked blatantly wrong, would you read a 100 page document first to see if you should leave it alone or would you change it?

    There’s nothing wrong with including bits of the specification as comments. Yes its redundant, but redundancy is generally a bad thing, its not always a bad thing. If redundancy was always a bad thing, your office would only have on bathroom.

  13. Jeff_NH says:

    Mostly agree with this and it is true today as it was 20 years ago when this was still well known and ignored by programmers.

    Having said that I would generally caution against comments that reference bugs, what we ‘used to do’, etc. I agree there are probably cases where that exact construct is reasonable but I think it is quite rare.

    Just as there is a tendency for people to do i++; // increment i

    there is also a tendency to suddenly start cluttering up the code with lots of inline comments about bug fixes and enhancements. This seems ok until you try to maintain code for 10 years and it is full of such clutter related to what used to be and what might have been that you can no longer follow the code. We have issue database, we have version control, most of the value of comments written in this way are provided by those assets.

    Certainly of there is a fragment of code that is particularly tricky where there the most natural way of writing it is wrong I could begin to see the wisdom of talking about the alternate approach, why it is wrong and slightly short circuiting the full discussion by reference to a full change record… Having said, I believe my ‘rule’ is essentially never do it for reasons similar to the never use goto rule.

    In both cases there are very valid reasons to use the construct (gotos and lots of discussion about when code changed as a result of a change request) but the typical programmer screws up the use of both of these at least an order of magnitude more often then they get it right.

    For example, this

      1: // This used to delete items older than 30 days, but

      2: // bug #65432 requested that an exception be made for

      3: // items that are of type X.

    Is interesting in many ways. It immediately brings to mind the question (for me) about why are you deleting items not of type X > 30 days old. What required/suggested that? What you appear to be doing here is using your bug/change tracking system as a requirements management system and then putting in the requirement ID in the code for traceability reasons. For an informal development process like this I’d much rather just see a statement that says (succinctly) why items of type X should be held.