Architecting for Change - Part I: Why Does It Matter?

Architecting for Change - Part I: Why Does It Matter?
Photo by freestocks / Unsplash

There are myriad reasons for change. Competition, evolving user expectations, technological advancements, regulations, bugs, security fixes, performance enhancements... the list is almost endless. Hence, change is inevitable, and systems must be designed to accommodate it. They need to be evolvable.

Systems not designed with change in mind risk eroding into a mess, a Frankenstein monster with changes bolted on randomly, entangling the system in undesired ways, adding considerable complexity, technical debt and undermining its quality attributes.

Change is inevitable; ergo, a good architecture must make it easier to make changes by minimising the cost of change. This is the reason why I like this particular definition of architecture from Grady Booch:

Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.
- Grady Booch

So, what happens to the system if change is ignored or not given the proper attention?

Technical Debt and Software Decay

Quick fixes and feature additions done without refactoring or design oversight lead to the buildup of technical debt. "Software rot” sets in – the codebase becomes brittle and hard to modify over time. As Ward Cunningham’s debt metaphor suggests, expedient decisions incur a “debt” that “makes future change more costly”.

As an evolving program is continually changed, its complexity, reflecting deteriorating structure, increases unless work is done to maintain or reduce it.
- Meir Lehman, Programs, Life Cycles, and Laws of Software Evolution

In other words, without refactoring (reducing debt), the software becomes harder to change. Each bit of unresolved debt adds friction to future modifications – that’s the interest paid. “Technical debt is not just the cost of change, it is the loss of alterability that makes change progressively more expensive" (Code Scene). In essence, if you do nothing, the cost of change keeps rising. Eventually, changes become so expensive or risky that they are either abandoned (resulting in missed business opportunities) or cause serious issues (bugs, delays).

Technical debt doesn’t only live in code; it can also take the form of architectural debt – broader design decisions that compromise the system’s structure and future adaptability. Architectural debt tends to have a high interest rate since it pervades the system, widening the change radius and hence significantly increasing the cost of change.

Architecture Erosion

Unguided changes erode the system's structure and architecture. If unchallenged, they could lead to bypassing proper abstractions/interfaces to directly invoke or use internal components, duplicating functionality, and oversharing data and, consequently, knowledge, in poorly designed APIs and messages. As a result, it blurs boundaries and creates tight coupling between parts of the system that were meant to be independent.

Boundaries

When boundaries are blurred, the ripple effect—and consequently the cost—of change grows significantly. The system as a whole becomes a less cohesive, more coupled mesh where almost nothing can change in isolation. In other words, a well-placed boundary helps isolate change and limits the blast radius when things go wrong - boundaries reduce unintended consequences.

“System design is inherently about boundaries (what’s in, what’s out, what spans, what moves between) and about tradeoffs. It re-shapes what is outside, just as it shapes what is inside.”
- Ruth Malan

Boundaries are essential to good design, where we want to separate what belongs together from what doesn't. We aim to be highly cohesive within the boundaries but loosely coupled outside them.

Boundaries are also about clarity: without boundaries, understanding a system becomes an exercise in archaeology. Boundaries help create resilient, evolvable systems where complexity can be localised and managed.

We need stable, impermeable boundaries to achieve high cohesion and low coupling and limit the ripple effect of changes.

"A structure is stable if cohesion is strong and coupling is low"
- Larry Constantine

Knowledge Flow

These boundaries are also knowledge boundaries; they determine what knowledge belongs together and what stays outside. They also decide which knowledge to keep private and what to expose.

Shared knowledge and assumptions directly affect coupling and complexity. The more knowledge we share, the tighter the coupling, the higher the complexity, and the higher the cost of change. Hence, we need to be judicious about the knowledge we expose and the assumptions we make about other components.

"The more knowledge that is shared, the more shared reasons for change the coupled components have; any changes to the 'knowledge' have to be propagated across the affected components."
- Vlad Khononov - Balancing Coupling

Knowledge affects various aspects of design and architecture, and it's a topic I'll explore further in this series, borrowing heavily from Vlad Khononov's excellent book.

Coupling

If we re-examine the quote from Vlad, particularly this part: "The more knowledge that is shared, the more shared reasons for change the coupled components have". Does this mean we could avoid the downsides of oversharing by eliminating coupling instead? Well, no. Coupling is an inherent part of any useful system, and, therefore, cannot be avoided.

"... a system is an interconnected set of elements organized in a way that achieves something."
Donella Meadows, Systems Thinking: A Primer

Coupling is either essential or accidental. Accidental coupling is self-inflicted due to "suboptimal design decisions," as Vlad Khononov states. The challenge is to eliminate accidental coupling whilst managing essential coupling - that's the basis of building modular systems.

Trade-offs

The final part of Ruth Malan's description of system design is trade-offs.

“System design is inherently about boundaries (what’s in, what’s out, what spans, what moves between) and about tradeoffs. It re-shapes what is outside, just as it shapes what is inside.”
Ruth Malan

Architectural trade-offs are the deliberate compromises made to achieve specific architectural characteristics over others. For example, sacrificing consistency for availability.

Unguided changes risk diminishing prioritised architectural characteristics or capabilities and consequently accepted trade-offs. These can be within individual components or across the system.

Changes in the environment and business may also necessitate changes in architectural characteristics; therefore, limiting the cost of change and increasing the reversibility of those decisions is vital to ensure the business's continual agility.

Rigid Organisations

Organisational structures mirror their architectures, and vice versa. If change isn’t explicitly architected for, organisations unintentionally embed rigid structures, reinforcing communication patterns that become inflexible. In other words, rigid systems tend to create rigid, siloed teams.

Organisations struggle with poor team boundaries and dysfunctional interactions if we fail to architect and organise for change. Teams become overloaded, cognitive load increases drastically, and the intended ‘flow of value’ slows.

Over time, organisational culture becomes defensive, rather than collaborative and innovative. As change becomes harder, teams slow down, reinforcing a fear-driven culture. Flow diminishes, causing organisational stagnation. Leaders may respond by increasing control or introducing more process overhead, reducing team autonomy and exacerbating social friction. Teams shift from problem-solving to crisis management, perpetually firefighting rather than strategically evolving.

We shape our architectures; thereafter, they shape us
- Gene Kim

Architecture and organisational structure go hand in hand; they constrain each other and, therefore, should be changed together and by the same group.

Complexity

Boundaries, knowledge flow, coupling, cohesion, technical debt, and organisational structure determine how additional, unnecessary complexity exists in the system. Like coupling, complexity is essential or accidental. Accidental complexity refers to the additional complexity that is not intrinsic to the problem being solved, but rather stems from our design choices.

All complexity is often treated equally as something unavoidable, but not being intentional about handling complexity effectively breeds more complexity. Discerning essential from accidental complexity is important, as is understanding the techniques to tackle complexity and looking at the ramifications of our decisions through a complexity lens - is a decision adding complexity? Can the complexity be reduced/eliminated if we choose a different option? Can we limit the scope of this complexity? Can we isolate it? And so on. Complexity is an important topic that deserves a designated post in this series.

Conclusion

The lack of foresight in managing the cost of change is a key driver of architectural entropy. Organisations allow complexity to grow unchecked, and architecture becomes increasingly incoherent and rigid. Without deliberate architectural evolution, the organisation's technical debt spirals out of control, leaving teams in a constant firefighting mode rather than focusing on strategic value. Coordination time and dependencies between teams increase, hindering flow and slowing down time to market, and consequently time to value.