Adept Software Development

Adept: (A)pplication (D)evelopment (E)nterprise to (P)ersonal (T)ransition. It is a system I am developing to leverage Enterprise developer skills to produce stand-alone software for other market segments. This is a general software development blog discussing issues about project, architecture, design and development. The emphasis will be in Java, but many of the issues will be more general. Almost all will be technical.

http://marringtons.com

Tuesday, July 12, 2005

What and where to document

Software developers believe in the holy grail of self-documenting code. Sorry, Sir Gawain - but it doesn't exist. Any developer who has gone back to maintain code written a month ago will often have as much difficulty understanding it as if it had been written by another. And yet still the developer will go to any length to write code but not comments. I know, I was one of the worst 'self-documenters' - and most developers who have worked for me still are.

My journey to code documentation nirvana started when I decided to port a 10 year old C++ library to Java. The names I had thought so descriptive then just baffled me now. They told me what, Clear code structure told me 'how' - but nothing told me 'why'.

Every now and then over the years I find myself fixing code written by my team. It's a good productive form of code review. I used to just put a comment against the end of changed lines with my initials, date and a comment on what was changed in one short sentence. I felt that this way I was not confusing the flow of the code. Silly. Why a problem occurred and how it was fixed provide important information that must be placed in the code. Otherwise the next person in line will reverse your changes to 'fix' another problem.

So I love JavaDoc. I have always believed that good documentation should be in the code. It's the only place of any use to maintenance staff - and later users of the class. Hava a look at my Adept library at http://library.marringtons.com/doc/javadoc. I hope you can see the difference between my documentation and the standard comments you see out there for open source projects. And internal commercial code documentation is not as good! Every good IDE uses the generated JavaDoc. When you pass the mouse over a method, you can get a description of why and how it's used - assuming it doesn't simply pop up with 'TODO.

Good JavaDoc is great for 'how', but it's still not enough for 'why'. 'Why' is the result multiplied by 1.1512? 'Why' are we looping through a list to get a single value rather than asking the database for it directly? For almost every active line of code in an application there is a story. And next time you need to maintain that piece of code, the story will be of immense value.

Don't try and go back to document all that old code. Whenever you make a change, however, give us the gossip. You won't regret it.

I'll leave you with an example of how I write code now.

/**
 * Collect common instanceData for all Panel commands.
 * Called before any command is executed.
 * @see com.marringtons.adept.action.Action#setup()
 */
protected void setup()
  {
    /*
     * First we retrieve the session scope panel data -
     * including a list of panels (opened and closed).
     */
    sessionData
        = (SessionData) request.session.get( panelCacheKey);
    /*
     * The panel ID can be from target or id HTML tag
     * parameters.
     */
    String id = parameters.get( "target", parameters.get( "id"));
    /*
     * If the command is not related to a particular
     * window then we cannot continue.
     */
    if (id == null)
      return;
    /*
     * We cannot be sure whether the id starts with
     * 'panel.' or not,It depends on where it was
     * generated in the JavaScript.
     */
    if (id.startsWith( "panel."))
      id = id.substring( 6);
    /*
     * We need to remove the ID from the parameters
     * so it does not add panel. back.
    parameters.remove( "id");
    /*
     * Given the id of a panel, retrieve it from a
     * panel instanceData structure in the session.
     * This instanceData can be updated and persists
     * between program runs.
     */
    instanceData = (InstanceData) sessionData.portals.get( id);
    if (instanceData == null)
      {
        instanceData = new InstanceData();
        instanceData.id = instanceData.title = id;
        instanceData.url = "";
        instanceData.showTab =
            instanceData.showBorder =
            instanceData.showShadows =
            instanceData.allowResize = true;
        instanceData.x = (nextX += 50);
        if (nextX > 600) nextX = 0;
        instanceData.y = (nextY += 50);
        if (nextY > 400) nextY = 0;
        instanceData.width = instanceData.height = 200;

        sessionData.portals.put( id, instanceData);
        instanceData.focusOrder = instanceData.openOrder
            = ++sessionData.focusCounter;
      }

    /*
     * Move parameters from the command line into
     * the instance data.
     */
    ObjectScraper.fromProperties( instanceData, parameters, null);
  }

 

0 Comments:

Post a Comment

<< Home