Published June 14, 2020
by Doug Klugh
Design your software in such a way that components are as abstract as they are stable. This supports the Stable Dependencies Principle and promotes flexibility by ensuring that stable components are easy to extend, even though they are hard to change. This is achieved by applying the Open/Closed Principle, which enables us to easily extend functionality without modifying existing code. This approach also works best when adhering to the Dependency Inversion Principle, which states that dependencies should point towards abstractions and not concretions. This provides very effective Dependency Management for software components.
You can build flexible, loosely coupled, and highly extensible systems by ensuring that your stable, abstract classes sit at the bottom of your component structure. These components encapsulate the classes that are hard to change. But that's okay, because this is where we put the code that does not need to change often. And if we design our system well, they won't need to change at all if we make them open for extension.
Our stable components can now support the unstable components located near the top of our component structure. With little to no incoming dependencies, these components encapsulate classes that are easy to change. And this is where we put the code that changes often.
All these engineering principles fit together really well, each supporting the principles and practices of the others. Building high quality software (i.e. loosely coupled, adaptable, extensible, testable, maintainable, scalable, resilient, etc.) is greatly simplified by applying these engineering principles and practices. The key is knowing why you should use them, how they work, and how to implement them. Conquer that and you're well on your way to building great software.