Open-Closed Principle (OCP)

Open-Closed Principle (OCP)

Open for extension but closed for modification.

OCP is part of SOLID design principles. OCP dictates that software entities should be open for extension but closed for modification. This principle ensures that existing, tested, and live classes remain unchanged while allowing new functionality to be added through extension rather than altering the existing codebase.

To achieve this principle, two approaches can be employed: inheritance and interfaces.

Using Inheritance: One way to adhere to the OCP is by utilizing inheritance. When an additional feature is needed, a new class can be created by inheriting from the original class and implementing the required functionalities. If modifications are necessary for the inherited methods in the child class, method overrides can be employed. This approach effectively decouples the parent and child classes, enabling seamless extension without altering the existing code.

However, there are certain disadvantages associated with this approach. In cases where shared methods among child classes require the same implementation as the parent class, maintaining consistency becomes challenging. Future changes may require revisiting the child class code, either by eliminating the override or duplicating the parent class implementation.

Using Interfaces: An alternative method to uphold the OCP is through the use of interfaces. The key advantage of interfaces lies in the absence of predefined method definitions in the parent class. This allows for the creation of diverse classes with distinct implementations. For instance, if the current implementation class becomes unsuitable or business logic evolves, a new class can be created that implements the interface.

By adhering to the Interface approach, changes and extensions can be seamlessly introduced without impacting existing classes. This enables the system to accommodate evolving requirements while maintaining stability and preventing modifications to live code.

Open-Closed Principle in E-commerce:

In the realm of e-commerce, the OCP ensures that the core functionalities of the system remain untouched while allowing for the introduction of new features or adjustments without altering existing, proven code. Let's explore this principle using both inheritance and interface-based approaches in an e-commerce scenario.

Using Inheritance:

// Original class representing a product in the e-commerce system
class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

// Extended class introducing a discount feature
class DiscountedProduct extends Product {
    private double discount;

    public DiscountedProduct(String name, double price, double discount) {
        super(name, price);
        this.discount = discount;
    }

    // Overriding the getPrice method to include discount
    @Override
    public double getPrice() {
        return super.getPrice() - (super.getPrice() * discount);
    }
}

Using Interfaces:

// Interface defining the contract for a product
interface Product {
    String getName();
    double getPrice();
}

// Original class implementing the Product interface
class StandardProduct implements Product {
    private String name;
    private double price;

    public StandardProduct(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public double getPrice() {
        return price;
    }
}

// New class introducing a special offer
class SpecialOfferProduct implements Product {
    private String name;
    private double price;
    private double specialDiscount;

    public SpecialOfferProduct(String name, double price, double specialDiscount) {
        this.name = name;
        this.price = price;
        this.specialDiscount = specialDiscount;
    }

    // Implementing the getPrice method to apply special discount
    @Override
    public double getPrice() {
        return price - (price * specialDiscount);
    }

    @Override
    public String getName() {
        return name;
    }
}

In this e-commerce scenario, the OCP is demonstrated through both approaches. In the inheritance-based approach, the DiscountedProduct class extends the Product class to add a discount feature. In the interface-based approach, the SpecialOfferProduct class implements the Product interface to introduce a special offer with a discount.

These examples showcase how new features can be seamlessly added to an e-commerce system without modifying existing, tested classes, by the OCP. This enables the system to adapt to changing requirements while maintaining the stability of existing functionalities.

Conclusion:

In summary, the Open-Closed Principle advocates for an extensible system where new functionalities can be added without modifying existing, tested classes. Both inheritance and interface-based approaches provide strategies for achieving this principle, with interfaces offering a stronger guarantee of flexibility and decoupling, ensuring the system's resilience to changes while facilitating individual class testing.