Protecting software components with the Open-Closed Principle
The?Open-Closed Principle (OCP)?[1]?says that software elements (functions, classes, modules, components, packages, etc.) should be open for extension and closed for modification. "Open for extension" means that we should be able to add new features to the software element in question. And "closed for modification" means that we should be able to add these features without touching the existing code.
At first glance, both requirements seem to contradict: how could we add new features to a software element without modifying it? There are multiple answers to this question, and this document gives one.
1. Example design
Let us consider that we have a class ProtectedImplementation that we intend to shield with the OCP principle. And we came up with the design shown in Figure 1.1.
We made the?ProtectedImplementation?realize the?ProvidedInterface. If the client requires a different behavior when using this same interface, we can provide an alternate implementation instead of modifying?ProtectedImplementation. The alternate implementation may use?ProtectedImplementation?or be entirely new.
To make ProtectedImplementation resilient to changes in its dependencies, we have introduced?RequiredInterface. First, we implemented the required interface using?DependencyAlternative1?(and its?NativeInterface) inside?DependencyAdapters.Adapter1. Later, for some reason, we decided to switch from?DependencyAlternative1?to?DependencyAlternative2?and created?DependencyAdapters.Adapter2?in response. When this change happened, we did not touch the?ProtectedImplementation.
领英推荐
2. Side-effects
When we designed the solution in?Figure 1.1, we found out that:
3. Conclusion
Shielding our implementations with the OCP makes them resilient to changes at the cost of a more extensive codebase. Protecting all the components in a project may not be feasible if the project has tight time constraints or may not be worth it if the expected lifetime of the project is short.
We can benefit from shielding our implementations with OCP when we want to produce a highly stable component in a large project.
Resources