Design Driven Development

Coding in the Small.

For me, TDD is a specification, design and documentation tool. From writing a test alone you can specify what you want, derive an intuitive interface and end up with a snippet of code as an example of how to use it. With this specification in place you also have a goal, the green bar – your tools will tell you when you’re done. And it’s hard to practise TDD without components that are all munged together, so loose coupling tends to appear. The fact that you get unit-tests for free is also a nice bonus which allows daring refactoring.

[Joe’s Jelly]

This is a revelation that crept up on me over time. Like (I’m sure) most developers upon stumbling across test-driven development, I initially fixated on the ‘test’ aspect of it. Its reasonably natural to do so, as everything stems from writing tests, its easy to assume the testing is the most important aspect of TDD. The fact is, test-first is an immensely powerful design tool, that also happens to leave you with loosely coupled, highly tested code. Bonus.

Interfaces considered Important

Coding Conventions – _I_ want to kill the Impl. This is actually a fun debate… I’ll wade in:

First, Cedric pontificated recently about using Hungarian notation in Java. You know, stuff like “lpszStringName”… You can just guess my thoughts: Oh. God. No. And this isn’t just because it’s a Microsoft thing, it’s because it’s damn ugly. And it doesn’t even make sense in Java… I think lpsz means something like “long pointer zero terminated string”. How does that even relate to a String object in Java? That’s generally what’s wrong with Hungarian notation, it just doesn’t fit most of the time (though I’ve seen people try).

Cedric then continues today (yesterday?) with some thoughts about interfaces – specifically using an I in front of interface names to differentiate between them and classes (e.g. “IWorkspace”). And THIS is where it gets interesting because Charles thinks that that’s about the most evil thing he’s heard in a while. Yeah! Let the beetle battle begin! (Sorry, too much Dr. Seuss lately…)

I detest, loathe, hate, and want to vomit on any class that ends with the letters “Impl”. UUUUGH! IBM stuff is super-famous for this. Almost everything that comes out of there has this convention going. It’s like someone at IBM skipped a chapter or two in the OO book and decided that classes were less important than interfaces, so the interfaces get all the readable names and the classes get a Impl stamped on their ass. It must have something to do with the IBM mentality. I don’t know. What I do know, however, is that classes are the principle objects in Java, not interfaces. Interfaces are handy, dandy and cool, but they’re there to help structure your classes and allow interoperation without multiple inheritance, NOT to be the prime way of programming. If you’re thinking “I’ll just program to interfaces and forget about those classes”, you need to come up to speed because I think that fad went out a couple years ago.

-Russ [Russell Beattie Notebook]

This is interesting, mostly because I used to agree, and now disagree (sorry Russ). I think interfaces are one of the most under-used and useful parts of Java. I certainly believe that if you do have a class and an interface that it implements, the interface gets priority, ie. the unadorned name of the thing. The class is usually ThingImpl (or SimpleThing, PersistentThing, etc). Because if there is an interface, then you really, really should be programming against that, and not the implementation directly. I seem to spend a lot of my time retrofitting unit tests to legacy code, and interfaces are my most powerful weapon in this arena. Non test-driven code is frequently tightly coupled and hard to pull apart. Making the legacy objects implement simple interfaces immediately gives me a point of leverage to pry apart the coupling, and stub out parts of the system with Mocks, or make the test cases themselves implement the interfaces. This lets me very quickly build ‘scaffolding’ around the parts I’m testing, and makes refactoring a much less fraught affair.

Not to mention that well thought out use of interfaces makes it possible to do all sorts of cool stuff with your code, like adding dynamic proxies. Which, as we all know, are pretty much the gateway to AOP, developer nirvana, world peace etc. etc.