Friday, 19 September 2008

Five principles of great coding

[caption id="" align="alignleft" width="300" caption="Photo by Martin Kingsley"]Photo by Martin Kingsley[/caption]

There are lots of principles you can adhere to when writing computer code.  In this article, we're going to look at a few of the more important ones!

Test as you write
As much as possible, test your code as you write it.  These tests will often be quick and easy ones, such as checking that the value of pi you're using is really what it should be, but if you perform these little checks while you're working on (and thinking about) that piece of code, you'll save yourself a lot more effort having to come back later and fix bugs.  You'll find that you can perform a lot of simple tests very quickly as you go along; once you're in the habit, you really don't spend a lot of time doing it.  But the time you save yourself later on can be considerable. As well as informal testing, using a test harness and writing automated tests will help guarantee code you have already written keeps doing what you expect and helps prevent bugs you have already fixed from reappearing.

Code re-use
Why spend time writing code when you can use some that's already been written?  Reusing existing code can be a great way to save great big chunks of time.  Libraries are the classic example, with the good ones being well-written, tested and documented, plus there's the added advantage that if lots of people use a library then it's less likely to contain glaring bugs because they'll have been found and fixed already.  The same time-savings can sometimes be gotten from old code you wrote or that you've been given, perhaps by a colleague, supervisor or boss.  Or even that you found on the web and downloaded.  Provided the code does the thing you want and that it runs correctly (you need to check that these are true!), you can again save yourself time and effort that you can then devote to other parts of the project.  There is a tendency to shy away from this third-party code (the so-called "not invented here" problem) because you don't fully understand how it was built and therefore don't trust it.  As with so many areas of life, skepticism is good, but don't fall into the trap of dismissing other people's code out-of-hand; there are a lot of very good software engineers out there, so that third-party code might be just what you're after and save you months of effort.

Reduce dependencies as much as possible
One very important consideration is to reduce dependencies as much as possible.  A dependency is a connection between two chunks of code, for example, using the same variable, and the more of these your code has, the more things you have to keep track of.  When writing and debugging a chunk of code, the last thing you want is arbitrary other chunks being able to interact with it, because it'll very quickly become unmanageable.   Much better would be for each chunk of code to be highly de-coupled from the rest of the code, with only very specific connections to the rest of the program.  This keeps things much simpler and easy to manage.  In practice, this means things like compartmentalising your code into chunks (which you were doing anyway, right?), avoiding global variables (with the possible exception of explicitly fixed constants such as PI) and the like.  If you're feeling keen, writing
object oriented code is excellent for this, as this has encapsulation built into the process.

Validate your data
At some point, someone will feed garbage into your carefully crafted code. In fact, part of your testing should be feed garbage input into your code to check that it recognises it! If your code is validating the data it is given then it should be able to deal intelligently with this, even if "intelligently" means "crash but tell the user what has gone wrong and why". Assertions are an ideal way to make the program stop as soon as something is wrong. They work by 'asserting' that something is true and if it isn't then the program stops.

For example:

Assert(x >= 0)

If the variable x is less than zero then the program will immediately stop at this point.

During development this kind of information is invaluable and since the program has stopped at the first point it spotted something wrong, you don't have to work backwards from a garbage final output to find where the program failed.

Handle errors nicely
Asserts are a great way of validating data and are very useful during development, however once a program is in the hands of the users you want your error handling to be a little nicer than stopping the program immediately.  There is nothing more frustrating than a program that just dies without warning or explanation. Most modern languages have support for handling problems your code encounters using Exceptions. Exceptions are generated when something goes wrong and bubble up until they are caught and dealt with. The advantage of exceptions is that they can be used without your code having to pass around error-code results from function to function. Using exceptions properly is a complex subject, because the exception handling represents a different path through the code, but a simple rule of thumb is: 'Throw an exception when a problem is first encountered, catch it at the first point that can deal with it'. In programs with a GUI (Graphical User Interface) this usually means there is a catch-all at the user interface layer that displays a message to the user (or something similar) before attempting to save the data and then shutting down.

These are some examples of great principles to adhere to as you develop your software.  They don't take much effort, once you get used to them, and the time (and headaches!) they can save you make it well worth the effort!

Reblog this post [with Zemanta]

1 comment:

  1. jackson john kulwa4 October 2013 at 18:54

    i have understood well thank you.