Does TDD shun reuse?
by Kevin Dangoor
Mike Hogan asks whether Test Driven Development discourages component reuse. He gave a simple, clear example where he made a “grep” routine more flexible by delegating some of the function to other interfaces. My response:
Reusability is not really orthogonal to function, but comes as part of the function. Because we’ve all been taught in school that changing software is really expensive, the tendency has been to generalize software where it’s not required. If you never plug a new logger or regex provider into that code, the extra effort (and obfuscation) that comes in the ReusableGrep is just not worth it.
If it’s a customer requirement that the grep routine supports those plug points (and you’re delivering an API to them), then that should indeed be tested for and written. If someone is really doing test driven development, they will write those tests.
Or, if in the course of meeting customer requirements, you find that you’ve created a Log4JGrep and a JDK14Grep, then you’ll create the pluggable form through the course of normal refactoring.
I’m echoing some of what Rod said in his post, but I do think that the simplicity aspect is one of the critical parts of being agile. The point is that you don’t add additional layers for the sake of reusability until there is a customer need that requires it.
Kevin,
I understand what you and Rod are saying. However…
I still think reuse is orthogonal to function, because the grep function can be written in more than one way, some of which are more suitable to reuse.
“If its a customer requirement” for the component to be reusable then it can be made so. True. But this puts the future of reuse in the customers hand. Personally I want to see a community of reusable open source components that many developers invest in and use, and I’m taking steps to help make this happen. I don’t see it happening if we’re all dependent on the customer writing a story than talks about enabling plug points.
Doing the simplest thing that could possibly work is inarguably the best way I have found of solving my current problem. It cuts my cloth to exactly measure my current requirement. But where is the growth here? Are we always going to be cutting the same cloth to measure new requirements? I personally want to go beyond this, even if it means maintaining some extra stuff in my current project.
Note, I would not advocate always implementing a component with plug points. I am not advocating “extreme pluggability” in the same way as I am not advocating “extreme simplicity”. I am advocating some subjective decisions, like if you think you have a reusable candidate, based on your engineers instinct, I would encourage you to make it pluggable. And I would encourage you to submit the interface to a component repository …. to be discussed later
“Personally I want to see a community of reusable open source components that many developers invest in and use, and I’m taking steps to help make this happen.”
If that is the goal, then yes indeed the components should be made reusable, and the tests should reflect that. The “customer” in this case, is the community that uses open source tools in their development… even in API development it’s good to keep the customer in mind (I think Carlos Perez wrote something on that topic a few weeks ago). Only by having an idea of how people are actually going to use the components can the components be designed to meet what the people want.
On doing the simplest thing: “It cuts my cloth to exactly measure my current requirement. But where is the growth here?”
When I wrote my response, I had been thinking in terms of components built for a given project (or even a set of projects) where you control the code. API design for a component repository is a different game, because you can’t just change the API as needed. Doing the simplest thing assumes that you can change things later and that change is not horribly expensive because you have automated tests.
When building an API, you can still use test driven development, but the API you release to the public needs to have the right balance of pluggability and simplicity. Once it’s out there, it can’t change by much.
The Commons VFS project is an interesting example of how test can help even with pluggable implementations.
http://www.blueskyonmars.com/archives/2003_06_24.html#000894
BTW, thanks for crossposting