01 March 2009

Evolutionary architecture and emergent design: Investigating architecture and design

This article makes some interesting points.

Architecture:

A definition of architecture: "In most successful software projects, the expert developers working on that project have a shared understanding of the design system design. This shared understanding is called architecture. This understanding includes how the system is divided into components and how the components interact through interfaces."

Another definition of architecture: "Stuff that's hard to change later."

"One of the core ideas behind evolutionary architecture is to defer decisions as late as you can, which allows you to substitute alternatives that recent experience has shown are superior."

Essential complexity: e.g. business requirements in a payroll system that require the ability to define to allow certain members of staff extra days off. However, complexity in business requirements may not always essential, e.g. users requesting field level security in forms, which when live users realise are too fine-grained to manage.

Accidental complexity:
1) Just-in-time hacks to code - e.g. because of schedule or other external pressures. Compromises made now for the sake of expediency cause entropy to build up in your software. Entropy is a measure of complexity, and if you add complexity now because of a just-in-time solution to a problem, you must pay some price for that for the remaining life of the project (technical debt).
2) Duplication - duplication is the single most insidious diminishing force in software development because it manages to creep into so many places without developers even realizing it. The obvious example is copy-and-paste code, but more sophisticated examples abound. Duplication harms projects because it resists attempts to make structural changes or refactor toward better code. If you know that you need to change something in three different places, you avoid doing it even if it would make the code better in the long run.
3) Irreversibility - any decision you make that cannot be reversed will eventually lead to some level of accidental complexity. Irreversibility affects both architecture and design, although its effects are both more common and more damaging at the architectural level. Try to avoid decisions impossible or cumbersome to reverse. One of the mantras I've heard some of my colleagues use is to wait until the last responsible moment.
4) Rampant genericness - we seem to have a disease in the Java world: overengineering solutions by trying to make them as generic as possible. The motivation for this is clear: If we build in lots of layers for extension, we can more easily build more onto it later. However, this is a dangerous trap. Because genericness adds entropy, you damage your ability to evolve the design in interesting ways early in the project. Adding too much flexibility makes every change to the code base more complex.