Open Closed priciple - Dieptranivsr/DroneIVSR GitHub Wiki

Open/Closed priciple (OCP)

  • Classes/modules should open for extension but closed for modification.
  • This means you should add new functionality without changing the existing code.
  • Benifits - Increased Stability, reduced risk of introducing bugs when adding new features, and improved reusability.
  • Here is an example - Create different types of shapes
/**
  * Bad example
  **/

// If you want to add a new shape (e.g. Triagle), you'd have to modify the ShapeDrawer class
// by adding another if/else block. This violates OCP because you're modifying existing code
// to add new functionallity.

#include <iostream>
#include <vector>

enum clas ShapeType { Circle, Square };

class Shape {
 public:
    Shape(ShapeType type) : type_(type) {}

    Shape getType() const { return type_;}
    virtual void draw() = 0;
    virtual ~Shape() = default;

 protected:
    ShapeType type_;
};

class Circle : public Shape {
 public:
    Circle() : Shape(ShapeType::Circle) {}
    void draw() override { std::cout << "Drawing a circle\n"; }
};

class Square : public Shape {
 public:
    Square() : Shape(ShapeType::Square) {}
    void draw() override { std::cout << "Drawing a square\n"; }
};

class ShapeDrawer {
 public:
    void drawShapes(const std::vector<Shape*>& shapes) {
        for (const Shape* s : shapes) {
            if (s->getType() == ShapeType::Circle) {
                static_cast<const Circle*>(s)->draw();
            } else if (s->getType() == ShapeType::Square) {
                static_cast<const Square*>(s)->draw();
            } // Add more if/else blocks for new shapes - Violates OCP
        }
    }
};

int main() {
    std::vector<Shape*> shapes = {new Circle(), new Square()};
    ShapeDrawer drawer;
    drawer.drawShapes(shapes);

    for (auto shape: shapes) {
        delete shape;
    }
    shapes.clear();

    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️