SOLID Principles: Open-Closed Principle (OCP)

Amburi RoyAmburi Roy
2 min read

The Open-Closed Principle (OCP) is one of the SOLID principles of object-oriented programming.

Definition: Software entities like classes, modules, functions, etc., should be open for extension but closed for modification.

  • The “open” part says: We should only extend existing code to introduce new functionality.

  • The “closed” part says: Once a module has been developed and tested, the code should only be changed to correct bugs.

Goal: Reduce the risk of introducing errors or unintended side effects when making changes.

Advantages:

  • Modularized and improved flexibility in software system design.

  • Make software systems easier to maintain and extend.

  • Improves code reusability

  • Allows the creation of new features through composition and inheritance rather than modification.

Bad example:

class PaymentProcessor {
    public function processPayment($amount, $method) {
        if ($method === 'credit_card') {
            // Code to process credit card payment
          } elseif ($method === 'paypal') {
            // Code to process PayPal payment
        } else {
            throw new \InvalidArgumentException("Invalid payment method: $method");
        }
    }
}

Here, the PaymentProcessor class is not closed for modification. If we want to add a new payment method, we must modify the processPayment method, which violates the Open-Closed Principle.

This design makes the code brittle and requires changes to existing code whenever a new payment method is introduced.

Good example:

interface PaymentMethod {
    public function processPayment($amount);
}

class CreditCardPayment implements PaymentMethod {
    public function processPayment($amount) {
        // Code to process credit card payment
    }
}

class PayPalPayment implements PaymentMethod {
    public function processPayment($amount) {
        // Code to process PayPal payment
    }
}

class PaymentProcessor {
    private $paymentMethod;

    public function __construct(PaymentMethod $paymentMethod) {
        $this->paymentMethod = $paymentMethod;
    }

    public function processPayment($amount) {
        $this->paymentMethod->processPayment($amount);
    }
}

Here, we’ve created a PaymentMethod interface that defines the processPayment method. Each payment method (e.g., Credit Card and PayPal) implements this interface. The PaymentProcessor class is now open for extension but closed for modification. We can add new payment methods by creating classes implementing the PaymentMethod interface without changing the existing code.

Wrap-Up!

As a software developer, I sometimes struggle to keep the Open-Closed Principle (OCP) due to legacy code, adding layers that bring performance concerns, changing requirements, the need for abstraction, and uncertainty about future changes. It is crucial to carefully consider when and where to apply OCP to strike the right balance between flexibility and maintainability.

Happy Coding!

0
Subscribe to my newsletter

Read articles from Amburi Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Amburi Roy
Amburi Roy

A software engineer with over 13 years of experience navigating various tech landscapes on multiple domains, developed apps and microservices, and led transformative projects, all while embracing challenges with an innovative and enthusiastic spirit.