This is part II of a series on agile architecture. ].
In the previous installment, I provided a definition for software architecture and raised the apparent friction between the upfront design implied by software architecture and the YAGNI approach and deferred requirements prompted by agile development in the large. This installment takes a look at an additional angle of the problem, which is the difference between design and architecture (while architecture is a type of design. I am calling design here, the code or close abstractions of it that don’t yet fall under “architecture”, as defined in the previous post). The difference between the two, as the title suggests, is that while design can be emergent, Architecture, unfortunately, needs to evolve.
Unless you’ve been living under a rock, you probably already know about Test Driven Development (TDD) or its cousin BDD. If you’ve actually used TDD, you’ve probably noticed the impact it has on the actual code. Writing code only to cater for defined tests coupled with refactoring that keeps the design tight, we get to a result that, more often than not, is simpler than going through the more traditional design first (you can take a look at Uncle Bob Bowling Kata for a nice, albeit synthetic, sample)
In fact, a more accurate expansion of the TDD acronym is Test Driven Design. Yes, the tests are there to make sure the code adheres to the specified requirements. However, the iterative process (test, code & esp. refactor) makes the design emerge. The emergent design effect works very well with the goals and tenets of Agile and Lean methodologies as it helps eliminate wasteful future-proofing code that we don’t need, eliminate waste of extra components (due to pre-design) etc.
This sounds great, so taking that to the architecture level is very tempting. After all, architecture is a type of design, so wouldn’t it be efficient to do TDA (Test-driven architecture) as well? I think that, in theory, it might be possible. However, as the old adage goes, “Theory and practice are the same – at least in theory”. So, in practice, the problem is that architecture is global and has solution-wide consequences. Time and size (of work) constraints make us want to set the playfield for the solution as soon as possible. Architecture decisions are hard to postpone on the one hand and have extensive influence on the other. E.g., a buy vs. build decision, 3-tier vs. SOA, RDBMS vs a NoSQL solution, etc. If we try to have the architecture grow the way “regular” design can, the ripple effects will be devastating to the development process.
What we have to do instead is evolve the architecture. Start with something that is in the ballpark, and then when we know more about the problem, make changes and evolve the architecture over time. This is beneficial since requirements also tend to change over time, so if we find a way to evolve the architecture, we can also deal with that.
In the next part, I’ll try to give a couple of examples of how this can actually be done, i.e., how you can evolve an architecture.
[…] at Evolving Software architectures, with part 1 looking at the definition of software architecture, Part II – looking at emergent design andPart III looking at some do’s and don’ts on starting […]