Platypus Header

Platypus Innovation Blog

12 August 2014

Documentation for the Educated Stranger

When you're documenting an object/method/variable, ask: What would a stranger -- who knows basic coding & a bit about our project -- need to:

  • Get or make an instance of this object?
  • Use a class or function?
  • Edit this code?
Good documentation is invaluable. It enables new people to join the team, and it takes some of the pain out of code maintenance. It's a balancing act: It should be short yet clear. And of course, you don't want to spend too long on it.

The clearer you can make the code itself, the less documentation is needed (see the notes below on avoiding pointless documentation).
But: readable method and variable names alone are not enough to make code self-documenting.

Things to document:
  • Assumptions a method makes about the state of things.
  • Exceptions that may be thrown, and why.
  • Parameters whose meanings aren't obvious from the names. But there is no need to document the obvious.
  • Methods that may return null, and why.
  • When parameters can be null, and what that means.
  • Object lifecycle (i.e. how it is wired up and disposed).
  • Typical calling patterns -- how methods fit together.

The SoDash/Winterwell House Style

  • Prefaces you might use:
    • FIXME for we-really-should-do-this.
    • TODO for less urgent tasks.
    • ?? for questions / things your uncertain about.
    • NB for tangential notes, e.g. explaining why you didn't use alternative method X.
  • You can sign comments tweet-style with ^name or ^initials.
  • If you see code whose purpose or behaviour you can't understand, add a comment. E.g. "?? is this number a probability? ^DW April 2014"
  • Use assert in java, or SJTest's assert() and assertMatch() in javascript as a way to simultaneously test & document in-code assumptions.

How not to document

It's not about the amount of JavaDoc / JSDoc. It's the quality. Here's an example of pointless documentation:

/** {Object} */
var displayData;   

/** Get the display data for the part. 
* @param {string} url The url 
* @returns {Object} the display data.
function getDisplayData(part, url)

How weak is this?

  1. There's no point in doc which just restates the function/variable name. You are not writing for idiots.
  2. Type {Object} tells us very little! What kind of object is it?
    A common case is where Object is a lookup map, in which case
    say what the keys are. Consider using a name which clearly describes the lookup, e.g. tagsetFromTag is clear, whereas tagsets isn't.
  3. Parameters: Can they be null? What happens if they are?
  4. The input parameter url in this example is ambiguous: is this an absolute url, a relative url, or does it not matter because both will give the same output, or does it matter but which to use is specified elsewhere?
  5. Return value: can it be null?
  6. Lifecycle: when can this be called? E.g. does it only make sense after the page has done some initialisation steps.

Photo: Book sculpture by Daniel Lai, "Kenjio"

No comments:

Post a Comment

Good-Loop Unit