Monday, 24 January 2011

From Use-Case to Coding

How do you go about writing software? Is it an art or a science? Are classes created from the imagination or are they in the requirements waiting to be discovered? This blog is a stab at figuring this out by attempting to document how I currently approach coding. I’m assuming a lot: you have your development environment, you know what tools you’re using, you know your target environment, you know the system’s architecture and probably lots more besides.

To illustrate the process, consider the following fragment taken from a hypothetical use-case:

“The system will receive an XML messages from a JMS queue, check its validity, parse it and write the result to a database.”

So, you read the use-case and subconsciously do a little noun-extraction figuring out the class candidates which spring to mind and which patterns to apply. Your thought process may go something like this...

The use of a JMS indicates a MDB, which points to the fa├žade pattern, whilst the database and JEE point to a 4 tier model. From the noun extraction we can list potential candidate classes and turn them them into a model. Potential class candidates are:
  • An MDB class with an onMessage() call that implements the facade pattern: EventMDB
  • Some kind of service class tying together business functionality: EventService
  • One or more validation classes.
  • An XML Parser - XMLBeans or Xerces
  • Data access object(s) EventDao

From the list of possible class candidates above you now have a rough starting point, but nothing more. The next task is to solidify the relationships between the classes and for that I always find it best to create a class diagram.

There is a wide range of tools on the market for creating a simple class diagram and they vary greatly in price and complexity. The one I always favour has been on the market a long time and still works. It’s the PAP System, otherwise known as Pencil and Paper.

Here’s why:
  1. Low cost.
  2. Low learning curve.
  3. Quick and easy.
  4. Non-permanent.
The last point, non-permanent, is probably one of the most important. At this point in the design cycle, all you need is a rough idea of what you’re going to build, and your final class structure may vary considerably from this diagram.
What you don’t need to do is spend hours keeping your class-diagram synchronised with your code; experience demonstrates that it’s pointless as 95% of the time no-one will read your documentation after the code has gone live. If a class diagram is required for posterity, then do it at the end that way it’ll be accurate.

So, for our little event logging MDB, an initial starting point maybe:
Before you can your first write test, you need to roughly define what it is you’re going to test. Using our initial class diagram the final step before coding is to take a rough stab at the interface specifications of our classes: what methods do they contain? For example, we may decide that our EventDao uses CRUD; hence, we’ll implement a create() method, and that our validation classes will have validate() methods.

We’re now ready to start coding and I’m assuming that you’re going to use Test Driven Development (TDD), which, incidentally, is the most successful technique I’ve ever used.

TDD is well documented, so I’m not going to describe it here. The only advice to give is to be ruthless in the elimination of duplication; delete any code that doesn’t do anything; don’t be scared of changing the code and refactor often; rename classes, variables and methods appropriately; and rigorously apply the SOLID principals. Remember that you will be supported in your actions by the tests that you’ve written: a failing test is a good thing as it tells you how to fix your code.

To conclude, I’ve described a technique that will get you from use-case to coding and the more techniques that you have in your toolbox the easier life becomes.

No comments: