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);
}