My good friend Malcolm posted a response to my IFaP article and asked, in essence, “what is the minimum amount of architecture needed for a system built with Test Driven Design.”

I had to stare at that.  For me, TDD meant Test Driven Development, not Test Driven Design.  Search.Live.Com brought up Scott Ambler’s site where he clearly states his formula for Test Driven Design:

Test Driven Design = Test First Development (TFD) + Refactoring

Hmmm.  My training by one of the original authors of JUnit clearly calls the technique Test Driven Development, so it appears to me (perhaps unfairly) that Scott is redefining an acronym to mean more than it originally meant.  He is not the first to do this, of course. 

I truly dislike this aspect of our industry.  If an idea catches on, it becomes an acronym.  Then if someone has another idea they want to glue to the side of the first, they just redefine the acronym and say “it’s been this way all along.”  No.  It wasn’t.

Test Driven Development is a fairly low level coding activity.  Don’t count me as a critic.  I really believe that a combination of Pair Programming and Test Driven Development can really make for writing good code fairly quickly.  However, neither handles design.  Design has to be done first.

Mr. Ambler does have an answer to “when design happens,” called Agile Model Driven Development.  Unfortunately, it’s a waterfall process, so it’s hardly agile.  According to his site, there is a set of iterations on the models, just enough to get them ‘good enough’ and then you start coding using TDD.  Note that you never go back to the models.  If they were wrong, you fix it with refactoring.  You cannot iterate on the design itself.  No iterations based on feedback.  No incremental improvement.  It’s not agile.

I’m not calling this incorrect.  I’m calling this “not-agile.”  I don’t believe it is incorrect.  Perhaps our tools are just not ready for this kind of post-coding refactoring of the model.

I do believe that a project requires design up front, but it doesn’t have to be big design.  I don’t believe that you have to create every little detail in the diagrams, or even define much more than the interface and responsibilities for each independent component.  However, you DO need to define the following key elements right up front. 

This is the minimum agile architecture.

For each independent component:

  • In one or two sentences, describe the responsibility of the component.  Add one more sentence to clarify, if necessary, what the component will NOT do. 
  • Describe every endpoint, both inside the system and externally that your system calls.  For each endpoint, describe the Protocol used to communicate.  Describe every Unique Identifier that your system will use to look data up.  Describe the format of the data being passed to and from the endpoint (in a services-model, this is the canonical schema).  (Identifier + Format + Protocol = IFaP)
  • Describe the priority quality attributes that the endpoint must exhibit.  If an endpoint must be reliable, but should be performant, then you’d say “reliable first, performant second.” 

That should take less than three days, and should be done with two or three people working closely together, and then reviewed with the team to find things you missed.

Agile design is light.  It is enabled by tools.  It is defined well enough to get people to work independently of one another.  Describing the IFaP allows tests to be written to the interface first, so it can be coded using Test Driven Development.  Hopefully, if you do this well, the need for refactoring, at least before the first full release is out the door, is pretty slim.