Definition
It defines that our design or code should be open for extension but close for modification. In other word, open for extension means: when we create new base class then we need to design this base class such as way that (function in base class should be pure virtual) it can be extended easily by just adding new derive class. Close for modification means: we should not disturb the existing code for any new feature. If we are changing in existing class then our design is not good.
If we can support new feature just adding new derive class and we are not touching existing class then our design is following (OCP).
The Open-Closed Principle (OCP) is one of the SOLID principles in object-oriented programming, specifically in C++. The principle states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
This means that once a class or module is implemented and working correctly, it should not be modified directly to add new functionality or change its behaviour. Instead, the entity should be designed in a way that allows for extension or customisation without modifying its existing code.
To achieve the Open-Closed Principle in C++, you can use several techniques and design patterns, including:
- Inheritance and Polymorphism: By designing your classes to use inheritance and polymorphism, you can create base classes that define a common interface or behaviour, and derived classes that extend or modify the behaviour as needed. This allows you to add new functionality by creating new derived classes without modifying the existing code.
- Abstract Base Classes and Interfaces: Using abstract base classes or interfaces, you can define a contract or set of methods that derived classes must implement. This allows you to create new classes that adhere to the interface and provide different behaviour without modifying the existing code.
- Strategy Pattern: The strategy pattern allows you to encapsulate algorithms or behaviours in separate classes, called strategies, and use them interchangeably. By defining a common interface for the strategies, you can easily add new strategies without modifying the existing code.
- Template Method Pattern: The template method pattern provides a way to define the skeleton of an algorithm in a base class and allow derived classes to override or customise certain steps of the algorithm. This allows for extension without modifying the existing code.
By applying these techniques and design patterns, you can adhere to the Open-Closed Principle in C++ and create flexible, reusable, and maintainable code.
Source code with example:
#include <iostream> #include <vector> // Abstract base class representing a shape class Shape { public: virtual double area() const = 0; }; // Concrete classes implementing different shapes class Rectangle : public Shape { private: double width; double height; public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; } }; class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; } }; // A class that calculates the total area of a collection of shapes class AreaCalculator { public: static double totalArea(const std::vector<Shape*>& shapes) { double total = 0.0; for (const auto& shape : shapes) { total += shape->area(); } return total; } }; int main() { std::vector<Shape*> shapes; shapes.push_back(new Rectangle(5, 4)); shapes.push_back(new Circle(3)); double totalArea = AreaCalculator::totalArea(shapes); std::cout << "Total area: " << totalArea << std::endl; // Clean up for (const auto& shape : shapes) { delete shape; } return 0; }