DEV Community

Cover image for SOLID Principles: Open-Closed Principle (OCP)
Amburi Roy
Amburi Roy

Posted on • Edited on

SOLID Principles: Open-Closed Principle (OCP)

🪨 SOLID Principles

SOLID is a list of 5 software engineering principles. It is a meta acronym where each letter corresponds to another acronym:

Without any further ado, let's jump into today's topic:

Open-Closed Principle (OCP)

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");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)