Until now, people have perceived their software architecture as hard to change. But what if we build architectures with change and scalability foremost in mind?
An evolutionary architecture supports incremental, guided change as a first principle across multiple dimensions.
What drives change in software architecture?
Everything changes eventually. As Einstein famously said, it is the only constant. Some things may change by taking the initiative as an organization, other things will have to change involuntarily. There are two kinds of change your organization has to deal with:
- Business-driven change: This covers new revenue models, disruptive competitors, new channels, changing customer needs, market regulation and product innovation. These change the business requirements and use cases you are addressing with your architecture.
- Ecosystem change: The technical domain shifts and evolves as programming languages, libraries, framework tools and operating environments change. Docker, for example, helped to bring container technology to the masses. Consequently, this revolutionized the way we use computer resources.
Change can have a very strong impact because of the so-called Dynamic Equilibrium. A term typically used in chemistry and other physical sciences, it also holds true in software architecture. Dynamic Equilibrium means that when you change a finely-balanced condition, you’ll require continuous adjustments to maintain a stable state. Just like Yin and Yang, the software universe is dynamic rather than static. In a constant state of flux, any snapshot of your software architecture will differ depending on the moment it’s taken. So how do you handle change?
Dealing with the unknown
By its very nature, architecture is what you want to change the least since it’s the hardest and most costly thing to change. That’s why changes in the ecosystem can create real problems for software architecture, especially enterprise. The more things change, the less possible it becomes to do long-term planning. Predictability gets lost. How can you have a five-year plan for your architecture when it can be easily overthrown by some unfathomable innovation?
When you do anticipate change as an early adopter, you could also end up betting on the wrong horse, just consider failed programming languages such as D, Fortress, J# and Wasabi. Then think of new languages such as Scala, Typescript and Swift. Will they stay around? Or suffer the same fate as Ruby, that lost its momentum after Twitter announced in 2011 to move away from it. You simply can’t predict what will be the next most popular language. But when the shift happens, you’ll still need to plan the whole ecosystem that follows.
The Evolutionary Architecture approach by Thoughtworks
The only solution is to build an architecture that anticipates change and evolution, in a cost-efficient way. Rebecca Parsons, Patrick Kua and Neal Ford from Thoughtworks named this idea the evolutionary architecture. With this architecture, you can adapt quickly to change without the need to predict the future to make uncertain investments. Predictability makes way for evolution.
Evolutionary Architecture vs. Earlier Architectures
The guiding principle of an evolutionary architecture is to support guided, incremental, non-breaking change along multiple dimensions. To understand the implications, we’ll take a step back and consider the earlier architectures. The first, of course, is the big ball of mud, a software system that lacks a perceivable architecture. It’s dense and identifiable by the high coupling of its building blocks. One change requires many modifications that can put the entire application at risk: it’s breakable.
The second architecture to compare with is the layered or multitier architecture that separates the functions presentation, application processing, business logic and data management. It offers one-dimensional evolvability in a structural sense as you approach the layers’ dimension separately. But in practice, changes to lower-level interfaces tend to percolate to higher levels. And when you introduce new features on one layer, this can force changes on every other layer. Additionally, if you consider the principle of Domain-Driven Design (DDD), which centers on the business domains of the users, you’ll find that one domain is likely to be scattered across multiple layers. One change in the business domain will affect all the layers: it’s not evolvable.
Now, consider an evolutionary architecture such as microservices. There is a bounded context which is operationally distinct. Services are decoupled and domain-oriented, which means that changing an existing service does not impact other services. It’s like changing Lego.
The Principles of Evolutionary Architecture
The main idea is that architectural elements are changeable later. When you build in evolutionary change in your architecture, changes will become cheaper and easier. There are several concepts surrounding the evolutionary architecture:
- API: By using APIs as the framework for interacting with the applications, the data and functionality can be easily accessed by other applications.
- Cloud: Especially when you bring your microservices to the cloud, your architecture can take full advantage from typical cloud benefits like scalability, resilience and high-availability.
- Headless commerce: When you apply microservices for e-commerce, you can decouple the CMS from the presentation layer, in a so-called headless commerce
- Event-driven architecture (EDA): This approach focuses on business events to which the organization simply has to respond. An event-driven architecture serves its customers realtime and allows for defining the business logic as global logic.
While all these developments and approaches will give the business agility organizations today seek, the concept of the evolutionary architecture provides the overarching principle. It’s all about adaptability to change.
5 Key aspects to consider when designing an Evolutionary Architecture
- Fitness Functions. This specifies what the target architecture looks like and as such, will vary greatly per organization. Some systems require heavy security, others high-availability or certain levels of uptime. The up-front thinking about fitness functions guides decision-making and timing, and helps you to preserve key requirements as the system evolves.
- Last responsible moment. Traditionally, you make architectural decisions before writing any code. In an evolutionary architecture, you wait for the last responsible moment to make decisions. Why? Well, because there is likely to be more detailed information available to take into account. The challenge, though, is to determine which decisions you can postpone. Fitness functions should be leading here.
- Bring the Pain Forward. Some things are hard to do and have the potential to cause pain. When you do these earlier and more often, you will identify the issues causing this more rapid. As you get better at fixing these, you will be encouraged to automate the pain away.
- Continuous delivery. This allows you to support the broader practice of the evolutionary architecture, as it introduces two new architectural attributes: testability and deployability. In a testable architecture, you can discover most defects with automated testing. In a deployable architecture, you can deploy a particular service without significant orchestration or downtime. It also allows for experimentation and A/B testing, like running several versions of the same version at the same time.
- Organized around business capabilities. Using Domain-Driven Design, modularity is created at the domain level rather than along technical layers. That will require setting up cross-functional teams per business domain and changes the focus from one-time projects to ongoing projects. You build it, you run it. As a result, making non-breaking changes along well-defined boundaries gets simplified.
Timing is everything
The evolutionary architecture greatly improves the cycle time to get a single change into production, repeatedly and reliably. It does so by taking away slow feedback cycles, coupling and cohesion: the main obstacles for adapting to change. Each component of the architecture can evolve with time, independently of its environment. The drastic reduction in time to market and new adaptability will bring your organization real maneuverability and business agility. That allows you to efficiently adapt to changes, introduce new features at the right time and beat your competition. Because with an evolutionary architecture, you will be able to set your own pace.