Many software engineers are or have worked on ageing codebases. The nature of this universe and our species thrives on failure which fuels the engines of our evolution.
Now what this means in terms of systems we build, is that the rigidity is lost in our incessant need to evolve.
How does this happen?
In all new projects, we tend to engineer and be as far sighted as our release schedule permits. This often renders a system that is “current” with less than 20% of architectural debt. In some projects, the changes are pushed last minute from upper management but even in those extreme cases, technical debt tends to converge back to the 20% boundary.
With this reality in mind, when approaching a code base with history, it is important to find and distill its architectural primitives.
What are architectural primitives? These are comparable to design patterns but are usually in the form of components that affect every part of the code. They can exist but arent’ limited to being globals, singlentons, parent classes or object members. They are critical to initialiazation and refresh of the runtime states but they can also be prevalent before the code ever compiles. Think macro functions that inculcate debugging metadata for example. Although for the latter I’d rather call it architectural pillars.
Once these pillars and primitives are identified they should be documented and tracked. Over time new ones might arise and that’s okay. In general I’d wager that 4%* of the codebase should have these core components and anything more will lead to a code base that’ll be harder and harder to maintain and rearchitecture.
*Following The Pareto principal, 20% of codebase will be core features and 20% of that would be these pillars and primitives.