Tuesday, February 10, 2009

Agile Technical Specifications

A technical specification document attempts to bridge the gap between a business driven functional specification and the raw code pouring from a developers mind.

Yet technical specifications now belong to a bygone, pre-Agile age. Back then business people and technical managers collaborated to produce a functional specification intended to describe all the features of the final system. The technical specification was then derived from this functional specification. It was a structured document that described the system's architecture and intended features in unambiguous terms.

It is now understood that this top-down process is unrealistic. Agile is, in part, a response to the divergence between pragmatic coding and 'command-economy' management. Agile accepts that nobody can really specify a software system before the first versions of the code are written. Nowadays we realise that code must evolve alongside the specification with each informing the other and the whole informing the client in a system of mutual feedback loops. The rigid, top-down information flows of yesterday have given way to a much more flexible and dynamic approach to system specification, planning and construction.

But you don't know what you have until you lose it. Now technical specifications have gone the way of the Dodo I can't help thinking that they were not entirely evil after all. If we imagine a utopian technical specification that really did describe a complete system with no mistakes then this would surely be a very useful document.

Is there any way we can get to an Agile version of the technical specification? Can we achieve a technical specification that delivers the usefully specific technical information whilst still being agile, flexible and evolutionary?

I think so. I think that if I was given a set of automatically generated, pre-defined class interfaces and a corresponding set of unit tests then together these would constitute an Agile Technical Specification.

[Public Interfaces] + [Unit Tests] = [Agile Technical Specification]

Given a set of interfaces, my job as a coder would be to create an equivalent set of domain classes that implemented those interface contracts.

Given a set of unit tests my job would be to use all my creative powers to flesh out my domain classes until those unit tests passed.

If all the unit tests passed then I would have satisfied the functional requirements and this functionality would, perforce, be presented via a public API specified by the interfaces. In other words I would have translated my Agile Technical Specification into working code that both defined and self-certified its own features.

So how do we 'generate' the interfaces and unit tests that comprise an Agile Technical Specification? Well we certainly don't want to be writing these by hand. That would just put us back into the old boat where time constraints cause the code to relentlessly drift away from the specification. Instead these artefacts need to be automatically generated if they are to be of any use.

If they are to be auto-generated then what specifies and drives the auto-generation? The answer is an Agile Functional Specification. Technical specifications are always derived from functional specifications, the difference is that now this process will be automatic.

Fortunately Agile Functional Specifications already exist. They are the sets of user stories that evolve in conjunction with the client or their business representatives. This implies that as the user stories evolve so the Technical Specification will evolve as an automatic derivative.

To achieve this the user stories must be written in a context-aware structured syntax, in other words a domain specific language (DSL). Then it will be possible to consume the user stories and from them auto-generate both the interfaces and the unit tests required to create an Agile Technical Specification. The interfaces are derived from the user story setups and the unit tests from the user story 'Where' clauses (constraints).