📝 What You’ll Learn
- What the Open/Closed Principle means
- How to apply it in your code
- Real-world examples
- What goes wrong when OCP is ignored
📖 What Is the Open/Closed Principle?
The Open/Closed Principle states:
Software entities (classes, modules, functions) should be open for extension, but closed for modification.
In short:
You should be able to add new behavior without changing existing code.
🧱 Applying OCP in Code
Let’s look at an example that violates the principle:
❌ Violates OCP
public class NotificationService {
public void send(String type) {
if (type.equals("email")) {
// send email
} else if (type.equals("sms")) {
// send SMS
}
}
}
Every time a new notification type is added, you must edit this class — which breaks OCP.
✅ OCP-Compliant Design
Use polymorphism and abstraction to extend without modifying:
public interface Notification {
void send();
}
public class EmailNotification implements Notification {
public void send() {
// send email
}
}
public class SMSNotification implements Notification {
public void send() {
// send SMS
}
}
public class NotificationService {
public void notifyUser(Notification notification) {
notification.send();
}
}
Now you can add new types (like PushNotification) without touching existing code.
🧪 Real-World Example
Imagine a discount system:
Bad design:
class Discount {
double calculate(String type) {
if (type.equals("student")) return 0.9;
if (type.equals("vip")) return 0.8;
return 1.0;
}
}
Better with OCP:
interface Discount {
double apply(double price);
}
class StudentDiscount implements Discount {
public double apply(double price) {
return price * 0.9;
}
}
class VIPDiscount implements Discount {
public double apply(double price) {
return price * 0.8;
}
}
⚠️ Risks of Violating OCP
- More bugs with every new feature
- Low scalability
- Hard to test and maintain
- High chance of breaking existing features
📘 Recap
- OCP promotes extension over modification
- Add new features by writing new code, not rewriting old
- Use interfaces and inheritance for flexibility