Evolutionary Architectures: Designing for change

One true trait of software systems is that they’re never finished. What once started as a small seed will eventually become a complex, growing, breathing organism within your organisation. And while most tech organisations spend a lot of time on improving quality, extensibility and agility on an implementation level, far less emphasis is put on the same traits on an architectural level.

The traditional architecture

In software architectures, complexity follows a diverging path. The divergence correlates to the time a software system is under development and the increase of features and logic. In most traditional architectures, this increase of features mostly forms around the newer edges of a system, while older - often proven - logic is defined at its core.

In traditional architectures, this inner core is where the initial architectural foundation was built; it’s where the project started and serves as the birthing ground of all other functions that preceded it. During the start, a design phase was put in place to ensure all potential future requirements could be locked into the chosen solution and technology stack, decisions which would have to cover validity throughout the system’s lifetime.

In fully self-built systems, this inner core is often defined by the infrastructure and development platform, extended with the foundations necessary to succeed in the problem domain an organisation is operating in. In buy & build systems, the used e-commerce system, ERP, order management systems, or other supporting systems are often defined as the core. At the same time, additional functionality is scripted or combined with a plugin that allows an organisation to extend.

As time passes, the architecture and its complexity grow, and new functionality is increasingly constrained by the initially defined foundation.

Two routes are often taken here; either architectural principles – and the resulting loss of quality – in the codebase for the added functionality has to be lowered, or the core has to be extended with additional layers to supply implementors with the necessary productivity.

It’s this progression which often places software architectures in a brittle state. Accepting a mismatch in the core foundation’s design will raise the complexity of adding new features to an unproductive level. Expanding the core with additional layers will often reduce modularity and increase coupling throughout the codebase or solution. It’s not the new functionality that pushes an organisation into re-platforming programs; it’s when the core foundation of their software architectures reduces their agility and delivery to such a point that they lose a competitive edge in time-to-market.

Incremental change as a first principle

Organisations understand the need to adjust to changing market conditions to stay viable. With evolutionary architectures, the same traits are embedded in its core principles. While common wisdom often still defines the necessity of large upfront architectural design – because changing structure is believed to be difficult at a later stage – evolutionary principles embed incremental change as a first principle.

The point in time when an architectural design ought to be finished is one of the major distinctions between traditional ways of building systems and one which follows an evolutionary route. Decisions around the initial minimal technology, patterns of integration and deployment methods still have to be made. Still, decisions about the system’s structure, specific tools and supportive systems are pushed to the “last responsible moment”.

In simpler terms, it means setting up the core of the system and its architectural patterns to its most flexible minimum and embedding the ability to decide on later requirements as its foundation. While it requires a mind shift and accompanying learning curve, building evolutionary change within a software architecture makes it simpler and inevitably cheaper to change large parts of the system when necessary.

Taking an ERP as an example

For example, let’s define a “traditional” way of implementing an ERP system within an organisation. While initially only necessary to replace an old finance system, ERPs often also bring solutions for order management, warehousing and fulfilment processes. Therefore, we often see selection processes that not only look at an answer for a specific department’s needs but also try to take the automation of other potential departments into account.

Before the first step of implementation and integration has been made, a long design process is started to define database structures, integration methods and business logic for current and future requirements. After a long implementation program, the ERP is specifically designed, configured and programmed for finance’s initially defined needs and is cluttered with assumptions for the other departments.

The moment the ERP is put to use, finance requires a different way of working, and additional layers of functionality are added. Warehousing is determined to be outsourced, and the codebase and configurations are adjusted so that the initial foundation can be misused to control the external data streams.

We’ve all been there and know where it ends. This traditional approach of obsessing over the initial form and structure limits the flexibility to provide the organisation with the best solutions when it needs them. Additionally, the often highly integrated - but coupled - solution minimises the ability to align the system properly with changes in business direction. Modifications on top of modifications eventually result in a solution where the knowledge of how the system should and was expected to work is lost.

Back to square one.

Using an evolutionary mindset, a best-of-suite direction would have been a better fit—one where we could’ve released an initial solution for finance in our architecture at a faster pace. A selection process both on initial features as well as the flexibility, extensibility and ways of integration we defined as core architectural principles. Taking a direction where knowing our architectural principles allow us to think about designing the extension of our system at the last necessary moment. Additionally, when a solution for warehousing was required, we could have factored it in later – thereby separating the solutions’ lifecycle from the finance systems.

This mindset of delayed, emerging or evolutionary design makes the impact smaller and the start of a re-platform easier. In parallel, it dramatically minimises the impact of future changes in your system.

Embracing controlled complexity

At its true core, evolutionary architecture design is about accepting the fact that the symbiotic relationship between software solutions and a business continues forever. Still, its form and function are never near a final state. Accepting that we can’t escape the growth of complexity, but instead embrace and accommodate this growth in the core of our architectural principles.

Properly designing systems that allow evolvability isn’t always trivial. It’s not about migrating towards a micro-service architecture, serverless, switching to headless or going full SaaS. Whatever technology you choose or is recommended to you, you will make it or break it just like you’ve done before. Instead, it’s about embedding a shift in mindset in how you select, design, build and embed software solutions into your organisation. Not approaching architectural design as something where you design and build a house, but as properly defined patterns as a navigation system for your organisation throughout its journey.

This article starts a series about evolutionary architectures, describing design factors for evolutionary design and common implementation patterns in the next editions.

Vorige
Vorige

Evolutionary Architectures: multi-dimensional evolvability

Volgende
Volgende

Collaboration over segregation