DEV Community

Cover image for Solid Principle : Open/Closed Principle
Vishwas Kapte
Vishwas Kapte

Posted on

Solid Principle : Open/Closed Principle

The Open/Closed Principle (OCP) is one of the SOLID principles in object-oriented programming. It states that a class should be open for extension but closed for modification. This means that the behaviour of a module can be extended without modifying its source code.

Benefits

The Open/Closed Principle (OCP) has several benefits in software design. Adhering to this principle can lead to code that is more maintainable, flexible, and scalable. Here are some of the key benefits:

  • Extensibility: The primary benefit of the Open/Closed Principle is that it promotes extensibility. By designing classes to be open for extension, you can add new features or functionalities by introducing new classes rather than modifying existing ones. This reduces the risk of introducing bugs in the existing codebase.

  • Maintainability: When classes are closed for modification, it becomes easier to understand and maintain existing code. Since you don't need to alter the code to add new features, there is less chance of unintentionally introducing errors in the existing functionality. This makes the codebase more stable and easier to manage over time.

  • Scalability: OCP facilitates the scalability of your software. As your system grows, you can introduce new classes or modules to extend its capabilities without changing the existing code. This allows your software to evolve and adapt to new requirements without disrupting the existing functionality.

  • Reduced Code Coupling: Following the Open/Closed Principle tends to reduce the coupling between different parts of the code. Because new functionality is added through extension rather than modification, the existing code is less likely to depend directly on the details of the new features. This results in a more modular and loosely coupled architecture.

  • Code Reusability: When you design your classes with the Open/Closed Principle in mind, you create reusable components. The classes and modules designed for extension can be reused in different contexts, promoting code reusability across various parts of your application.

  • Enhanced Collaboration: OCP facilitates collaboration among developers and teams. When the existing code remains stable, multiple teams or developers can work on extending the system concurrently without stepping on each other's toes. This leads to a more efficient and collaborative development process.

  • Easier Testing: Since new features are added through extension and do not require modifications to existing code, it becomes easier to test the new functionality independently. This separation of concerns simplifies unit testing, making it more straightforward to verify that the new code works as expected without affecting the existing behavior.

Let's consider a real-time example in C#/.NET to illustrate the Open/Closed Principle using a payment system:

Scenario:
You are building a payment processing system, and initially, it only supports credit card payments. Later, you need to extend the system to support additional payment methods without modifying the existing code.

Without Open/Closed Principle:

public class PaymentProcessor
{
    public bool ProcessCreditCardPayment(double amount)
    {
        // Logic for processing credit card payment
        Console.WriteLine($"Processing credit card payment: ${amount}");
        // Additional logic specific to credit card payments
        return true; // Payment successful
    }

    // Problem: If a new payment method is added, you would need to modify this class.
}

Enter fullscreen mode Exit fullscreen mode

In the above example, the PaymentProcessor class processes credit card payments. If you want to add a new payment method (e.g., PayPal), you would need to modify this class, violating the Open/Closed Principle.

With Open/Closed Principle:

public interface IPaymentProvider
{
    bool ProcessPayment(double amount);
}

public class CreditCardPaymentProvider : IPaymentProvider
{
    public bool ProcessPayment(double amount)
    {
        // Logic for processing credit card payment
        Console.WriteLine($"Processing credit card payment: ${amount}");
        // Additional logic specific to credit card payments
        return true; // Payment successful
    }
}

public class PayPalPaymentProvider : IPaymentProvider
{
    public bool ProcessPayment(double amount)
    {
        // Logic for processing PayPal payment
        Console.WriteLine($"Processing PayPal payment: ${amount}");
        // Additional logic specific to PayPal payments
        return true; // Payment successful
    }
}

public class PaymentProcessor
{
    private IPaymentProvider paymentProvider;

    public PaymentProcessor(IPaymentProvider paymentProvider)
    {
        this.paymentProvider = paymentProvider;
    }

    public void ProcessPayment(double amount)
    {
        if (paymentProvider.ProcessPayment(amount))
        {
            Console.WriteLine("Payment successful");
        }
        else
        {
            Console.WriteLine("Payment failed");
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

In this improved version, the Open/Closed Principle is followed. The PaymentProcessor class depends on the IPaymentProvider interface, and concrete payment providers (CreditCardPaymentProvider and PayPalPaymentProvider) implement this interface. Now, you can easily add new payment providers without modifying the existing PaymentProcessor class.

Usage:

class Program
{
    static void Main(string[] args)
    {
        IPaymentProvider creditCardPaymentProvider = new CreditCardPaymentProvider();
        PaymentProcessor creditCardPaymentProcessor = new PaymentProcessor(creditCardPaymentProvider);
        creditCardPaymentProcessor.ProcessPayment(100.0);

        IPaymentProvider payPalPaymentProvider = new PayPalPaymentProvider();
        PaymentProcessor payPalPaymentProcessor = new PaymentProcessor(payPalPaymentProvider);
        payPalPaymentProcessor.ProcessPayment(50.0);
    }
}

Enter fullscreen mode Exit fullscreen mode

This adheres to the Open/Closed Principle, providing a flexible and extensible design for handling different payment methods without modifying existing code.

In summary, the Open/Closed Principle promotes a design philosophy that values extensibility and maintainability. By following this principle, developers can create more modular, scalable, and adaptable software systems that are easier to maintain and extend over time.

I hope this can help you to understand Open Closed Principle. I'd love to see what you can come up with!

Thank you for reading and feel free to comment or connect with me LinkedIn and GitHub .

Top comments (0)