There is also an opposite idea though:future-proof architecture. It aims at creating systems that are unlikely to be obsolete or to fail in the future. This sounds very appealing. If we can build a system that can fulfill future requirements, we will have saved time and effort that would otherwise be spent continuouslyevolving it.
However, there is an assumption behind this. You need to predict the new requirements and you need to be right. That is equivalent to knowing the future. Itrarely happens.
If you are certain about requiring a feature in the future, then it is neither a prediction nor a future requirement. It is simply arequirement now.
This does not mean that we should build systems based on short-term objectives or take shortcuts. Instead, we should build systems that are ready to adapt to new requirements but not havethese implemented.
Capacity planningshould not be mistaken for future-proof architecture. Capacity planning is an operational concern related to deployment and physical resources. For instance, building a road to handle twice the current traffic is different from building a branch of the road that goes nowhere. Leaving headroom for expansion, extra volume, and extra traffic is part of the readiness for evolution. Capacity planning is an NFR, not a future requirement. We would not want the system to run on edges that may collapse in response to a fluctuation in the volumeof requests.
This mindset leads to a few outcomes. The software architecture aims for modular, extensible, and flexible components that are ready to make changes when theybecome necessary.
It implies that each component is highly cohesive but loosely coupled. It means that interfaces are small and specific. It also means that interactions among components are based on abstract interfaces and not concrete implementations. It further means that subclasses conform to the behaviors of their superclasses and are ready to be extended. Furthermore, it means that each component has only one reason to change. It also means that modifying a component does not require recompiling the entire system. It also means that concerns are separated so that when we want to adjust system quality attributes, we can address the particular concernin isolation.