What is Open-Closed Principle?
Table of contents
Introduction
The Open-Closed Principle is a fundamental principle in software engineering, which states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that the behaviour of the software should be easily extensible without modifying the existing code.
In this blog post, we will explain the Open-Closed design pattern in detail, including its benefits, components, and a real-world example.
Benefits
Increased Maintainability: With Open-Closed design pattern, new functionality can be added without changing the existing code. This reduces the risk of introducing new bugs into the codebase and makes it easier to maintain.
Flexibility: The Open-Closed principle enables developers to add new features to the codebase without affecting the existing code. This allows for a more flexible and adaptable software system.
Reusability: Open-Closed design pattern promotes the reuse of existing code. By extending existing functionality, developers can create new features that can be reused in other parts of the system.
Components
The Open-Closed design pattern consists of two main components:
Abstract Base Class: The Abstract Base Class provides a base implementation for a set of related classes. It defines a common interface and provides default behaviour for the related classes.
Concrete Implementations: Concrete Implementations are classes that implement the Abstract Base Class. They provide specific behaviour that extends the base implementation.
Structure
+----------------+ +----------------------+
| Client | | PaymentProcessor |
+----------------+ +----------------------+
| | | + processPayment() |
| + makePayment()|<------------| |
| | | |
+----------------+ +----------------------+
/\
|
|
+---------------------+
| |
+---------------------+ +--------------------+
| CreditCardProcessor | | PayPalProcessor |
+---------------------+ +--------------------+
| + processPayment() | | + processPayment() |
| | | |
+---------------------+ +--------------------+
Example
Let's consider an example of a payment processing system that accepts different payment methods such as credit cards, PayPal, and wire transfers. We want to implement a payment system that can easily add new payment methods without modifying the existing code. We can use the Open-Closed design pattern to achieve this.
First, we create an abstract base class, PaymentProcessor
, that provides a common interface for all payment methods. This base class has a method called processPayment
that takes the payment amount as input and returns a boolean value indicating whether the payment was successful or not.
public abstract class PaymentProcessor {
public abstract boolean processPayment(double amount);
}
Next, we create concrete implementations of the PaymentProcessor
class for different payment methods. For example, we can create a class for credit card payments:
public class CreditCardPaymentProcessor extends PaymentProcessor {
public boolean processPayment(double amount) {
// Implement the credit card payment processing logic here
return true; // Return true if the payment was successful
}
}
We can create similar classes for other payment methods such as PayPal and wire transfer.
Finally, we create a PaymentProcessorFactory
class that creates instances of the PaymentProcessor
based on the input parameter:
public class PaymentProcessorFactory {
public static PaymentProcessor createPaymentProcessor(String paymentMethod) {
if (paymentMethod.equals("creditcard")) {
return new CreditCardPaymentProcessor();
} else if (paymentMethod.equals("paypal")) {
return new PayPalPaymentProcessor();
} else if (paymentMethod.equals("wiretransfer")) {
return new WireTransferPaymentProcessor();
} else {
throw new IllegalArgumentException("Invalid payment method");
}
}
}
Now, we can use the PaymentProcessorFactory
to create instances of different payment methods, as shown below:
PaymentProcessor creditCardPaymentProcessor = PaymentProcessorFactory.createPaymentProcessor("creditcard");
creditCardPaymentProcessor.processPayment(100);
PaymentProcessor payPalPaymentProcessor = PaymentProcessorFactory.createPaymentProcessor("paypal");
payPalPaymentProcessor.processPayment(200);
Conclusion
The Open-Closed design pattern is a powerful principle in software engineering that promotes extensibility, maintainability, flexibility, and reusability. By designing software systems that are open for extension