Wednesday, January 7, 2009

Tests Drive Good Design

Test-first development leads to better design in the production code. Specifically, you get much lower coupling (both internally and externally), and you get much higher cohesion.

For those of you unfamiliar with those two terms, Coupling is tying one class to another. For instance, if ClassA relies on ClassB to do some work in such a way that a break in ClassB causes unit tests for ClassA to break, that's coupling. We try to limit coupling so that individual classes are isolated. We will always be coupling our classes to a degre (if java.lang.String breaks, everything breaks), but we try to keep it to a minimum. We want classes with low coupling because it is easier to isolate change.

Cohesion is how well the responsibilities within a class relate to each other. Highly cohesive classes tend to be small chunks that are easy to understand because they have a single responsibility. If you are tempted to answer the question, "What does this class do?" by using the word "and" a bunch, then you have a class with low cohesion. We want classes with high cohesion because they are easier to understand and thus easier to change.

When you write good unit tests, especially when you write them first, its easy to detect classes that are NOT highly cohesive and have low coupling. Tests become much more difficult to write when you stray from sound coding practices. If you weren't writing unit tests, you might be tempted to simply "new up" a dependency. Testing drives one to inject dependencies to create better seams and better class isolation.

The bottom line is that testable code is better code. It is easier to change, easier to understand, and overall easier to support.

No comments: