Open-Closed Principle (OCP)

By | September 28, 2020

This principle says that a class should be written in such a way that it performs its job flawlessly without the assumption that people in the future will simply come and change or modify it. Hence, the class should remain closed for any modification, but it should be open to getting extended. Ways of extending the class include:

  • Inheriting from the class
  • Overwriting the required behaviors or functions from the class
  • Extending certain behaviors of the class

If other developers are not able to design desired behavior due to constraints put by our class, then we should reconsider changing our class.  I do not mean here that anybody can change the whole logic of our class, but he/she should be able to override the options provided by software in an unharmful way permitted by software.

If we take a look into any popular framework like struts or spring or Hibernate, we find that we cannot change their core logic and request processing, but we modify the desired application flow just by extending a few classes and plugin them in configuration files.

For example, the spring framework has a class DispatcherServlet. which acts as a front controller in Spring MVC for Spring-based web applications. To use this class, we do not require to modify this class. All we need is to pass initialization parameters and we can extend its functionality the way we want.

You should also note that apart from passing initialization parameters during application startup, you can override methods as well to modify the behavior of the target class by extending the classes.

Another excellent example of the open-closed principle we can understand with the help of browsers. Do you remember installing extensions in your chrome browser?

Basic functionalities of the chrome browser like surfing different websites remain the same but if you want to check grammar when you are writing an email using a chrome browser? If yes then you can simply use the Grammarly extension, it provides you grammar check on the content.

This process where you are adding things for increasing the functionality of the Chrome browser is an extension.  Hence, the browser is a perfect example of functionality that is open for extension but is closed for any modification. In simple words, you can enhance the functionality by adding or installing plugins on your chrome browser but you cannot build anything new.

Why is this principle required?

The open-Closed Principle (OCP) is really very important since classes may be used by us through third-party libraries. We should be able to extend those classes without worrying if those base classes can support our extensions. But inheritance may lead to subclasses that depend on base class implementation. To avoid this, the use of interfaces is recommended. This additional abstraction leads to loose coupling.

Let’s assume developer X needs to release an update for a library and developer Y wants some modification or add some feature on that then developer Y is allowed to extend the existing class created by developer X but developer Y is not supposed to modify the class directly. Using this principle we separate the existing code from any modification so it provides better stability, maintainability and minimizes changes as in your code.

An example to clarify this principle:

Let’s assume we need to calculate areas of various shapes. We are going to start with creating a class for the first shape Rectangle which has 2 attributes length and width.

Next, we are going to create a class to calculate the area of this Rectangle shape. Which has a function calculateRectangleArea(Rectangle rectangle) which takes the Rectangle as an input parameter and calculates its area.

So far so good. Now let’s assume we get our second shape Circle. So we create a new class Circle with a single attribute radius as below.

Then we modify AreaCalculator class to add a new method calculateCircleaArea(Circle circle) to calculate the area of  Circle

However, You can see that there were flaws in the way we designed or created our solution above.

Let’s assume we have a new shape Square. In that case, we will again end up modifying/changing the AreaCalculator class. When the types of shapes increase this becomes really messy as AreaCalculator keeps on modifying and any consumers of this class will have to keep on updating their libraries which contain AreaCalculator. As a result, AreaCalculator class will not be baselined(fixed) with every time a new shape comes it will be modified. So, this design is not closed for modification.

AreaCalculator will need to keep on adding their computation logic in a newer method for upcoming shapes. We are not really expanding the scope of shapes; rather we are simply doing a piece-meal(bit-by-bit) solution for every shape that is added.

So we need to Modify the above design to comply with the opened/closed principle:

Let’s see how a more elegant design that solves the flaws in the above design by adhering to the Open/Closed Principle. We will first of all make the design extensible. For this, we need to first define a base type Shape(Interface) and have Circle and Rectangle implement the Shape interface.

Now Here there is a base interface Shape and all shapes now implement the base interface Shape. The shape interface has an abstract method calculateArea(). Both circle and rectangle provide their own overridden implementation of calculateArea() method using their own attributes.
We have brought in a degree of extensibility as shapes are now an instance of Shape interfaces. 
The last point I would like to mention here the above-mentioned consumers of these shapes. In our case, the consumer will be the AreaCalculator class which would now look like as below. 

This AreaCalculator class now fully removes our design flaws and gives a clean solution that adheres to the Open-Closed Principle. 

You May Also Like:

Template Pattern
Chain of Responsibility Pattern
Mediator Pattern
Strategy Pattern
Observer Pattern
Command Pattern
State Pattern
Visitor Pattern
Memento Pattern
Interpreter Pattern
Iterator Pattern

That’s all about the Open-Closed Principle
If you have any feedback or suggestion please feel free to drop in below comment box.

Leave a Reply

Your email address will not be published. Required fields are marked *