In the first part of this Object-Oriented Design principles series, I covered the Single Responsibility Principle (SRP). I had also covered the Liskov Substitution Principle (LSP) on a previous post. So let’s move on to another Object-Oriented Design Principle.
The Open Closed Principle (OCP)
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification
We know that requirements will change, new requirements will come and we will need to change some existing code during the life of a project. However, when a change in one place results in a cascade of changes in other classes, that’s a sign that the design is not quite right. Changes causing side effects are undesirable since it makes the program unstable, rigid and fragile where parts can not be re-used.
The Open Closed Principle target all problems described above. Being open for extension means that modules can be extended in order to make them behave in a new or different way. Closed for modification means that we should not change existing code unless that we are fixing a bug.
There were two proposed ways to achieve the OCP and both use inheritance:
- Dr. Bertrand Meyer, that coined the Open Closed Principle in 1988, proposes the use of inheritance. When a new feature or a changing on an existing feature is needed, a new class must be created, inheriting from the old one. The new class does not necessarily keep the same interface.
- A few other authors redefined the OCP in the 90ies. Basically they suggested the use of abstract base classes and concrete implementations. The abstract class would define the interface that would be closed to modifications. The concrete classes would implement the abstract class interface (open for extension) and multiple implementations could be created and polymorphically substituted for each other.
Nowadays, with the evolution of frameworks with dependency injection capabilities, a better approach would be having a client class pointing to an plain Java interface and inject the implementations.
OCP is an old OOP design principle and is one of the most important ones, due to the problems it solves. It can be an interesting approach in cases where the bureaucracy of changing old code and deployment to the production environment is very high. Some companies may ask for code reviews, a long test cycle (non-automated), documentation, etc. With OCP, no existing code is changed and just new code is added.
However, in a more agile environment, good test coverage, IDEs that have good re-factoring tools (like Eclipse, Idea, etc) I wouldn’t be too worried about changing classes and interfaces but this would not invalidate all the advantages of the OCP.