Evolutionary software design has become increasingly popular in the ongoing Agile discussion. Proponents of Evolutionary Software Design (ESD) advocate an organic approach to software architectures in which design is allowed to evolve along with the requirements of the software.
A colleague of mine is fond of saying, “The second programmer pays for generality.” He means the programmer should not consider how the software might evolve when implementing current requirements. The first programmer to the problem should write code to solve his problem efficiently and well, but without considering v2.0. This makes sense in an environment where the business requirements change too quickly for v2.0 to be dependably planned while v1.0 is being created.
ESD can be effective or terrible depending on how it is defined. The underlying principal required for ESD to work well is simple; Competence. Thoughtful implementation with relentless refactoring is crucial.
Streamlining the Evolution Process
There is a term for software written without first considering architecture: Spaghetti Code. I am not saying that you need a detailed architecture overview and prescribed UML model delivered from the architecture team, but neither should you dive into a problem without a strategy.
The proliferation of frameworks, patterns, and design guidance available to developers is richer than ever. Rare is the non-domain specific problem that has not already been solved and blogged. Is re-inventing the wheel really a good choice when we have so much collective wisdom available? I think not.
Successful ESD does include (Big D) Design. Some decisions are required up front. This means we must make decisions such as Monorail vs. ASP or nHibernate vs. Datasets and many others. Additionally, is it really a bad idea to predict logical extension points for your application and build in abstractions for them in v1.0?
Frameworks and Techniques
Once a framework has been used in the implementation of software, it is exceedingly difficult to remove that integral part of the architecture. This isn’t necessarily a bad thing, it is just a thing. Recognize that choosing Spring is a long term commitment for that application.
You know what they call decisions like that? Design.
That’s not all the up front design we need, either. Other matters of design include the implementation techniques. I have another colleague who will fight to the death on how to structure XSL templates. His ideas are good practice, to be sure, like always having an <xsl:apply-templates select=”*”/> in each template. This is good design and good technique. We can make the decision to implement this way before we write our first line of code.
Logical Extension Points
Another area of debate among the ESD purists is whether to plan for logical extension points within the application. I propose that this issue gets to the heart of why we still need developers in house and cannot off shore everything.
There is genuine value in understanding the business domain and product roadmap for the software being implemented. This is why good developers understand not just how to write code, but also the business problem their code solves. If we are good developers and we do understand our business domain, then we can make reasonable and informed decision about where we should plan our extensions. Ignoring this and refusing to build abstractions into v1 on principal is tantamount to dereliction of duty.
Implementing abstractions in v1.0 results in software which is more easily tested and therefore has higher quality. Planning your abstraction points around logical extension requests from your clients is just good practice. This is the kind of decision making that will come out in a meeting 6 months from now as “That’ll cost a lot,” or, “That’s an easy addition. I just need to implement a new SpoodleWidget.”
Conclusion
ESD is good. It provides a way to focus on what is important and not get sidetracked. Temper your ESD approach with a bit of wisdom and a penchant for writing less code and you really have something.
As with all things Agile, this falls under the #1 rule: Do What Makes Sense.