Apple TV: Nice hardware, shame about the limitations

October 22nd, 2008

Recent weeks have seen me busy spinning, i.e. achieving very little on the technology front outside of work. A nasty cold and related sinus issues has kept me away from computer screens as much as I can get away with but now at last the problems are receding and I’m starting to get traction again. Read the rest of this entry »

Effective Java Second Edition

September 16th, 2008
I recently picked up a copy of the second edition of Effective Java having owned a copy of the first edition for several years. Its a book I have always recommended to anybody new to Java because whereas many books on Java discuss the letter of the language, this book discusses the spirit, and puts it into clear context, leaving the reader in no doubt of (a) how to use particular language features, but (b) where and why to do so. Read the rest of this entry »

Method Contracts! Method Contracts! Method Contracts!

July 14th, 2008

I recently spent a few days back-filling test code to help a team meet one of its its quality objectives – namely unit test coverage – and the scany level of documentation within the code re-enforced my views on properly documenting the contract of a method. The methods I wrote tests for had the minimum of JavaDoc, enough to ensure no warnings from Eclipse, but nothing beyond that. So I had an idea of what the method was supposed to do, and roughly what the arguments were for – but no indication if null was a valid value for a given argument, or what would happen if an argument value was non-null but invalid.

To write tests for the method contract I had to pick through the underlying code – far from ideal, as I’m now inferring the contract from the code, and the code may not be correct. And this particular organisation hadn’t adopted the de facto approach to validating method arguments as documented in the excellent Effective Java (recently re-issued for Java 5) by Josh Bloch.

Briefly, the method contract consists of two component parts: the explicit contract – the method name, arguments and their types, and the implicit contract – which arguments can be null, the valid range of values for a numeric argument, etc. The degree of documentation for a method and its contract should be proportional to its complexity and the level of exposure the method is likely to receive – and it doesn’t get much more exposed than a component interface, so these should be very well documented indeed. The objective is to leave no ‘wriggle room’ in the specification – either for those developing an implementation or those who might want to use it. Or indeed, test it.

By providing thorough documentation for a method you are in effect crystalising the purpose of that method. As a developer it clarifies what you are trying to achieve; for a user of the method it helps them to understand what the method does and how to use it correctly. It should also tell them what error conditions exist and therefore allow them to be catered for.

This may seem overkill for a one or two man project, and you may be justified in short-circuiting the process to an extent. However it is vital in larger projects, and putting the documentation with the method ensures that future maintainers and users of the code do not have to hunt around for supplementary documentation. Or the original author, to explain what is going on. And even for a one man project, coming back to code cold after, say, 18 months, you might just find that the documentation refreshes your memory…

Briefly, the method contract consists of two component parts: the explicit contract – the method name, arguments and their types, and the implicit contract – which arguments can be null, the valid range of values for a numeric argument, etc. The degree of documentation for a method and its contract should be proportional to its complexity and the level of exposure the method is likely to receive – and it doesn’t get much more exposed than a component interface, so these should be very well documented indeed. The objective is to leave no ‘wriggle room’ in the specification – either for those developing an implementation or those who might want to use it. Or indeed, test it.
By providing thorough documentation for a method you are in effect crystalising the purpose of that method. As a developer it clarifies what you are trying to achieve; for a user of the method it helps them to understand what the method does and how to use it correctly. It should also tell them what error conditions exist and therefore allow them to be catered for.

Testing, testing

February 13th, 2008

There’s a lot to be said for test driven development. Next to documenting the code, testing is the other bane of a developer’s life that prevents them from moving on and doing other, ‘more interesting’ work. All the better then that the approach to writing code should include the writing of test cases. Write some code, write a test case, make sure it passes, then OK, move on to the next bit. You build confidence in the existing code as you add to it.

Done this way testing doesn’t need to be all that boring. And one of the keys to this is the structure of the code you test. Listen carefully when you ask why testing is a bind and what you’ll find is that developers don’t necessarily mind writing test code, its the work in setting up the right data for the test cases that takes the time. And then updating it as the system evolves. What is happening here is that the unit test exercises an entire monolith of code which in turn requires more detailed configuration than just the one class being tested. And because so much code is being exercised, a change in any area can result in tests in other areas failing. And so the myth that testing is time consuming is perpetuated, because the unit test isn’t a proper unit test.

Producing testable code doesn’t take much additional foresight and in a way is connected to one of the key tenets of OO design – correct assignment of responsibilities. If classes are small and tightly focussed then they are easier to test. Likewise methods – are your methods properly decomposed and does each method have a single clearly defined purpose? If the answer is ‘no’ then you are building code that is harder to test. Moving up a level, you should be designing components with clear and clean interfaces, and using standard techniques such as the Business Delegate pattern to minimise coupling between them. Which, in turn makes it a relatively simple matter to implement component stubs to support the isolated testing of classes, which in turn wipes out much of that data set-up issue.

In short, difficulties in testing OO code can often be ascribed to the structure of the code. Here is a list of points to consider:

  • Write many small, focussed classes rather than fewer, big classes.
  • Restrict methods to performing a single purpose – decompose ruthlessly.
  • Refactor shared/duplicate code into super-classes or helper classes as appropriate.
  • Don’t expose private methods unnecessarily just to make testing easier – use something like the PrivateAccessor class from the JUnit Addons project.
  • Create interfaces for components to allow simple stubbing.
  • Avoid static methods wherever possible.
  • Use the Business Delegate class to minimise coupling between components.
  • Use JUnit to build tests, and Emma to check your coverage

And as I’ve touched on Emma, an excellent tool which allows you to see, line by line, which code has been tested and which has not, I shall finish by briefly discussing test coverage. How much of your code should you test?

Your quality department would probably say “100%” but unless you’re working in a high-risk area (for example, fly-by-wire flight systems for airliners) then you probably won’t have the resources to do this. My take on unit testing is as follows:

  • Don’t write unit tests for bean getters and setters (I’m assuming here that your getters and setters do only that, and contain no complex processing), but do make sure they are exercised.
  • Don’t write test cases to demonstrate that assertions are thrown correctly (you are using assert, aren’t you?).
  • Maximise test coverage on your framework code (errors here will affect your system across the board)
  • Prioritise test coverage on your functional code. Focus on the more complex, riskier and shared code first.
  • If you are back-filling tests on code that has already shipped, focus on those areas causing the most disruption to your customer or support team.

If you’ve written small classes with tightly focussed code, it is actually quite difficult to get your coverage beyond 90% anyway, and the cost of completing those few extra percentage points will, for most situations, far outweigh the benefits.

Next time, the importance of the method contract.

Welcome to the Software Engineering Blog

February 8th, 2008

Welcome to the Surfsoft Cnsulting blog. Maybe it’s my age (I am over 40 after all) but in the last few years I’ve occupied senior positions in development teams where I’ve spent significant amounts of time trying to educate people not just in how to write code well, but how to undertake the whole software engineering process properly. Development is 80% engineering process and 20% technical skills – a good engineer will pick up new skills quickly and so knowledge of sound engineering practice is extremely important but usually under-rated.

Writing code is, to many developers, the most enjoyable and creative aspect of their work. Many of us, and I’m as guilty as the next person from time to time, rush through design in order to get to the fun bit. However there is a lot more to producing a successful piece of software than just cutting code. My intention in this blog is to share my own experiences and offer advice and suggestions to allow people to better understand and operate within the software engineering process, and to ultimately produce better quality software. Aside from that I will also be blogging about general tech/geek things close to my heart but not necessarily directly relevant to software engineering, but hopefully of some interest.

Before I start blogging in earnest I’d like to tell you a little about myself. You can find out about my career by viewing my public profile on LinkedIn so here I shall focus on the technologies I’ve used, and am using, rather than who I’ve worked for and when.

At Coventry Polytechnic (now Coventry University) I studied Information Systems Engineering and learnt Pascal and C, and assembly language (Z80, 6502, 6809 and 68000) although I already had good knowledge of Basic and assembly language (Z80 and 6502) from school and my trusty ZX81. During my Masters degree (Real Time Electronic Systems at Bradford University) I also studied Ada and Occam.

Between 1988 and mid-1997 I worked with Pascal, Fortran, Cobol and C, along with Ingres and a bit of Sybase on Unix and VMS systems. Between 1997 and 2001 I worked exclusively with Oracle – PL/SQL, Forms and Reports, and from 2001 I have worked exclusively with Java, J2EE and Oracle and MySQL databases. Many languages, several operating systems and a multitude of software engineering processes and configuration management systems.

As far as methodologies go, Waterfall and RAD (Rapid Application Development) reigned until I moved to Java, where iterative development and the RUP (Rational Unified Approach) were initially the mainstays of my development processes. Iterative development still rules but for the last couple of years I have also been working in SCRUM environments.

At this point I should make it clear that everything posted here is my own, personal viewpoint. I am not attempting to represent the views of my current, or any past, employer, and nothing I post should be taken as a criticism, explicit or implied of any of my employers.

And finally… I’m not a brilliant diarist, so please don’t expect regular postings. Lots of postings, yes, but there will be gaps.