TDD and design methodologies

(something I posted on our internal agile alias, in response to a question about how design works in TDD…)

There’s an underlying assumption in software engineering that “more design == better design”, despite that fact that the vast majority of us have worked with baroque systems that answer a bunch of questions that nobody ever asked.


The traditional theory is that if you don’t do the up front design, your code will be poorly architected, inflexible, and you’ll be in trouble when you try to maintain it. Which is true. But it’s also true that up-front design – especially the “spend a milestone” type of up-front design – often leads to the same result.


The ideal architecture is a minimalist one. It provides all the features that are needed and no features that aren’t needed (I mean “features” in the class method sense, not the user-visible sense)


The up-front approach attempts to do that without the data around which features are needed and which ones aren’t needed, which always changes along the way.


TDD says, “We’re going to figure out what we need and how to put it together along the way. We know we’re not going to get it exactly right the first time, but with our tests we can refactor as necessary



Comments (6)

  1. MSDNArchive says:

    Convince devs that something "test driven" is worth considering? Hmm. I think a new name for TDD would help.

    – Drew

  2. CHash2 says:

    I agree always:

    This is what I think the minimalist design should aim at:

    1. Very High level component level design (without which it might be difficult to understand the system itself)

    2. Class Diagrams: (We can understand all the objects that are needed and not needed)

    3. Sequence Diagrams: Expose the features/functionality and communication between layers in the design.

    4. State Diagrams: (In some complicated cases but not for every sequence)

  3. Haacked says:

    A corrolary is that you don’t know how to solve a problem till you’ve started solving it.  TDD helps with that in a disciplined manner and "regressionable" manner.

  4. piers7 says:

    I think it’s the *minimalist* bit that’s the key here. Many people (and I include Joel Spolsky in this) assume that agile / TDD means *no* design at all. This is just plain wrong, as the briefest of visits to the agile manifesto reveals:

    "we have come to value … responding to change over following a plan… that is, while there is value in the items on the right, we value the items on the left more"

    This is a call for lightweight, flexible planning, not no planning at all.

    Doing TDD doesn’t abrogate the developer’s responsibility to think about what he’s doing. The classes and components may tend towards cohesive and uncoupled, but it’s important to keep a hand on the tiller as the overall architecture evolves, and to have a few backup plans if contingencies arise.

  5. Agreed.  TDD mandates the definition of what HAS to happen, and then you code to that.  Agile mandates that you code the simplest solution that could possibly work, as they say in XP.  But — and this is where the misunderstanding seems to come in — neither of those directives absolves you of all consideration of coupling/cohesion, protected variation, etc.  Once you pass a unit test, that’s where the agile focus on refactoring comes in, allowing (even encouraging) you to apply design-level concepts.  

  6. Troy Hall says:

    Something that simply works may not be responsive, secure, maintainable, manageable, scalable, operationally low-cost, etc. Each of these attributes is addressed at the architecture/non-local level. Design is a "local" task – it defines what happens for a particular situation or context. Proper architecture design and guidance is still a necessary part of all serious development. Fortunately, many tools and techniques – various IDEs, MVC, messaging, proxy – are based on good architecture practices that we rarely think of them as architecture, or architecturally significant. The downside is that a lot of this is taken as granted, and important aspects of a system’s quality may be simply overlooked just to get things done. Realistically, how many TDD developers that you know build tests for performance and security up front? I didn’t think so…