Tuesday, March 08, 2005

Measuring OO-ness

Like most developers, I don't really care for software metrics. Writing good software is more like an art (or black magic, if you will) than an exact science. It takes years of learning and experience just to recognize good code, let alone writing it. A mathematical formula simply won't cut it for measuring code quality.

But still, I've always hoped that there'd be a simple method to determine how good an object oriented system is. The closest I've gotten was from a book (by Martin Fowler I think) that says something along the line, if you look at a good OO system, all the classes and methods are pretty small and simple and "don't seem to be doing anything"; it's through the interaction of these objects that complex behaviours emerge.

In our organization we have a separate "tools team" that does the builds for us. They use CruiseControl, bundled with everything under the sun: run unit tests and functional tests, provide test coverage reports through Clover, check coding standard using CheckStyle, run JDepend to analyze packages and cycles. But probably the most interesting is the class level design quality metrics produced by Essential Metrics. Of those the one that comes up most in our conversations is Cyclomatic Complexity.

Googling it will lead you to Software Engineering Institute's site that spits out a formula

Cyclomatic complexity (CC) = E - N + p

In reality it's a pretty simple concept. Cyclomatic complexity measures the number of decison points (if, else, for, while, switch etc) in each of your methods. The higher the number, the more complex your methods are, and in theory the more difficult it is to understand and maintain your system. The example I gave previously has a cyclomatic complexity of 7, which ranks at the top in our current small project.

But how is that related to how objected-oriented your code is? Well, over the years I've discovered that for a poorly designed OO system (if you can call it OO), it's almost impossible to avoid large amount of if's and else's, or worse, switch's. On the other hand, a well designed OO system (few and far between) has very light use of decision logic, usually only for checking boundary conditions (e.g. if argument is null). In other words, if your method is not "doing much", it probably has a low cyclomatic complexity.

low cyclomatic complexity == good OO code

As for the root cause of this, if you've come this far, you can probably figure it out yourself, right? :)


Post a Comment

<< Home