Open-Closed Principle (OCP)

Open-Closed Principle (OCP)

"Open Closed Platform" - Feeder Angler

The Open-Closed Principle (OCP) can be be described this way:

A software component should be open for extension but closed for modification.

In other words, when requirements change, the module should change as minimum as possible. Ideally, no changes. Developer should be able to extend a module by adding new code.

Lets take a look how would this look like from fisherman perspective. Imagine that we have seat box, which we want to expand with accessories like feeder arm and butt rest.

OCP SeatBox.png

From developer perspective this could be implemented by listing all accessories under SeatBoxAccessory enumeration class. Later SeatBox class could be initialised depending on the accessory we want.

enum class SeatBoxAccessory {
    feederArm,
    buttRest
};

class SeatBox {
private:
    SeatBoxAccessory accessory;
public:
    SeatBox(SeatBoxAccessory accessoryType) : accessory{accessoryType} {}

    void attachAccessory() {
        if (accessory == SeatBoxAccessory::feederArm) {
            printf("Attaching seat box accessory - Feeder Arm\n");
        } else if (accessory == SeatBoxAccessory::buttRest) {
            printf("Attaching seat box accessory - Butt Rest\n");
        }
    }
};

In case later new feature request comes, such as keep net attachment, then developer will have to modify SeatBox class. This class has not been designed according to OCP - it is open for modification.

Developer will have to understand SeatBox class to add new accessories. This could lead to unwanted defects. Also unit test will have to be reviewed and adjusted.

We can refactor this example so it wouldn't violate OCP:

class SeatBox {
public:
    virtual void attachAccessory() = 0;
};

class FeederArm : public SeatBox {
public:
    void attachAccessory() override {
        printf("Attaching seat box accessory - Feeder Arm\n");
    }
};

class ButtRest : public SeatBox {
public:
    void attachAccessory() override {
        printf("Attaching seat box accessory - Butt Rest\n");
    }
};

The SeatBox class is now containing very little code, new accessories now have their own implementation of how to attach itself. If new requirement arrives to attach new accessory - developer can create new Accessory class that implements SeatBox interface without having to make any changes in SeatBox class or any other Accessory class. It is now open for extension but closed for modification.