Open Closed Principle -SOLID design principles

Share the Article

What is Open/Closed Principle

Open/Closed principle is one of the most important principle for object oriented application designing. It is also contributing second letter “O” in SOLID acronym where O stand for Open/Closed. This principle tries to address future modifiability and maintainability issues of an application. Main idea of this principle is to achieve new modifications without impacting existing classes.

As clear from name, “Open/Closed” principle insists to design classes, such that classes are open for extension but closed for modification. Means we should design our class such that, modifications of existing classes for new features should not be possible. We need to extend the existing classes and support modification.

To get better results, our classes should support “Single responsibility” principle also. With Open/Closed principle, modifications is very easily achieved with better testability feature.

Why

Lets us try to understand the need of Open/Closed principle by taking an example of an application whose job is display video in formats such as:

  • Black & white
  • Colored

Example not using Open/Closed Principle

Lets us try to create an application without using the principle first.

Below is the sample application:

#include<iostream> //main header for io using namespace std;//for namespace enum VideoFormat { BLACK_WHITE, COLORED }; class DisplayVideo { public: DisplayVideo(string v) { cout<<" Video input received"<<endl; } void displayVideo(VideoFormat format) { switch(format) { case BLACK_WHITE: cout<<"Video displayed Format BLACK_WHITE" << endl; break; case COLORED: cout<<"Video displayed Format Colored" <<endl; break; default: break; }; } }; int main() { DisplayVideo d1("Input video"); d1.displayVideo(BLACK_WHITE); return 0; }

Suppose in future, we get requirement to support following new formats also:

  • HD
  • Ultra HD

Since, above class DisplayVideo already handles 2 formats – Black/White and Colored. Therefore, we will go and update existing class as below:

class DisplayVideo { public: DisplayVideo( string v) { cout<<" Video input received"<<endl; } void displayVideo( VideoFormat format) { switch(format) { case BLACK_WHITE: cout<<"Video displayed Format BLACK_WHITE" <<endl; break; case COLORED: cout<<"Video displayed Format Colored" <<endl; break; case HD: cout<<"Video displayed Format HD" <<endl; break; case ULTRAHD: cout<<"Video displayed Format Ultra HD" <<endl; break; default: break; }; } };

Drawbacks of above approach is that we have updated the existing class DisplayVideo. Who all are using Display Video will get need to get update . Plus, we need to update existing test cases also .

With above approach, both development and testing efforts got increased.

Open/Close principle is the best fit if we want to save efforts for both development and testing.

How

Let try to update the above class as per Open/Closed.

Thumb Rule – Classes should be open for extension and should be closed for modifications. We need to follow these rules :

Design an Abstract class and a member function

Firstly, create an abstract base class as DisplayVideo and and expose interface – displayVideo as below. Since Display video is an abstract class we have achieved now close for modification.

class DisplayVideo { public: virtual void displayVideo()=0; };

Provide concrete implementation of base class

Secondly , extend all format from DisplayVideo so that based on user request particular format can get displayed. We have achieved Open for modifications with this.

class DisplayVideo { }; class DisplayVideoBlackandWHite : public DisplayVideo { }; class DisplayVideoColored : public DisplayVideo { }; class DisplaYVideoHD : public DisplayVideo { };

Same Example now using Open/Closed Principle

Below is the updated application code with support for HD also:

#include<iostream> //Main header for io using namespace std; //for namespace class DisplayVideo { public: DisplayVideo(string v) { cout<<"Video input received"<<endl; } virtual void displayVideo() = 0; }; class DisplayVideoBlackandWHite: public DisplayVideo { public: DisplayVideoBlackandWHite(string v): DisplayVideo(v) { } void displayVideo() { cout<<" Video displayed Format BLACK_WHITE"<<endl; } }; class DisplayVideoColored: public DisplayVideo { public: DisplayVideoColored(string v):DisplayVideo(v) { } void displayVideo() { cout<<" Video displayed Format Colored"<<endl; } }; class DisplayVideoHD: public DisplayVideo { public: DisplayVideoHD(string v): DisplayVideo(v) { } void displayVideo() { cout<<" Video displayed Format HD"<<endl; } }; int main() { DisplayVideo *d1 = new DisplayVideoBlackandWHite("Input video"); d1->displayVideo(); delete d1; DisplayVideo *d2 = new DisplayVideoHD("Input video"); d2->displayVideo(); delete d2; DisplayVideo *d3 = new DisplayVideoColored("Input video"); d3->displayVideo(); delete d3; return 0; }

So, if in future we need to support Ultra HD format just extend Display Video for Ultra HD. No updation on client logic. Plus, for testing just need to write new test cases for Ultra HD class. No impact on existing test cases.

Pros & Cons of Open/Closed Principle

Pros

  • Easy to introduce or modify feature with less efforts.
  • Testability is very easy due to sub modules addition.

Cons

  • Due to addition of one more abstract class code complexity increased.

Main Funda: Open/Closed Principle ensures that a class remain open for extensions but closed for modifications.

Advanced C++ Topics

Single Responsibility Principle
Singleton Design Pattern
Factory Method Design Pattern
Builder Design Pattern
How std::forward( ) works?
How std::move() function works?
What is reference collapsing?

Share the Article

Leave a Reply

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