Thursday, July 2, 2009

Debugging revisited

There appear to be distinct methods of debugging, some of them more successful than others. When a project has a deadline, it is absolutely imperative that every detail is predefined and then cleanly implemented from the inside out. Analysis as you go development is increasingly stupid and bug prone so should be avoided at all costs no matter how one things one "can be more creative", or can defy logic by being able to "write clean code" when the code written has to be constantly revised.

Most systems stem from a database table relations guide. A recommended tool is Verio (so Microsoft bought it into their stable), but I prefer the Linux free offering Dia.

It allows you to outline class structures, creates lines of relation fairly well and then flesh out the objects with their bits and pieces. Very good. Verio does it better, but you do not want to be concerned with "features" of the interface when designing a system.

So, once the system is defined, it becomes increasingly important how you approach the system implementation. Most programmers start by defining an interface to the database or adopting one that is already defined and creating interfaces for the screens required of the designed system. Web designers are different - a page can be realised in HTML progressively. This of course may add functionality or features you did not account to in your database design. So the tendency is to start from the screen displays and then work out the database from that.

This sounds like a dilemma, but it is not, really. Make the database a little more fluid by implementation of a database tier that is a little "soft" (i.e. can be latently defined). There are numerous ways this can be achieved including attribute tables, linked lists and queues as well as traditional data tables.

A real n-tier system leverages the database against changing need, provides mid-ware that provides an interface that invites programmers to use it.

But still, bugs will occur. Especially when adding in new interfaces such as Ajax based systems - things become less clear when the back end starts serving event driven Javascript actions that respond to the back end. Therefore these interactions must be mapped or at least implemented via a framework.

Now to the debugging. When a bug can come from any tier or front or back end interaction it pays to a) have a map, and b) isolate the bug accurately.

It is important when you have a well defined structure not to change anything but the actual problem that is causing the issue. Before the bug is understood, there may be a period of familarisation with the segment of code, getting to know everything you can about a few lines of code may tell you more that testing ideas.

The bug often is not where it seems to be. Using conditional logging (so you can easily switch it all off) with debug levels enables code analysis. Take a leaf out of syslog - use a level indicator e.g.

logger = new Logger();
if ( debug > 3 ) {
logger::Log("this is a severe error");
} else if ( debug > 1 ) {
logger::Log("not so bad");
}

Of course it is better to leave the logger debug code in your code so long as it can be turned off. But when a piece of code is "clean" it is better for the distraction of the debugging phase be removed.

Use of svn or cvs make this delightfully feasible.