What if you could add new features without ever breaking your existing app?
Why Open/Closed Principle in LLD? - Purpose & Use Cases
Imagine you built a simple app that calculates discounts for products. Every time a new discount rule comes up, you open the existing code and change it directly.
At first, it works fine. But soon, the code becomes a tangled mess of if-else checks, and every change risks breaking something else.
Changing the same code repeatedly is slow and risky. You might accidentally break existing features. Testing becomes harder because changes affect many parts. It's like fixing a leaky pipe by patching holes everywhere instead of replacing the pipe.
The Open/Closed Principle says: design your system so it is open for extension but closed for modification. This means you add new features by adding new code, not by changing old code. Your original code stays safe and stable.
This keeps your system flexible and easier to maintain as it grows.
if (discountType == 'seasonal') { applySeasonalDiscount(); } else if (discountType == 'clearance') { applyClearanceDiscount(); }
class Discount { apply() {} } class SeasonalDiscount extends Discount { apply() { /* seasonal logic */ } } class ClearanceDiscount extends Discount { apply() { /* clearance logic */ } }
You can add new features without fear of breaking existing code, making your system more reliable and easier to grow.
Think of a music player app that supports new audio formats. Instead of rewriting the player each time, it adds new format handlers separately, keeping the core player stable.
Changing existing code often leads to bugs and slow progress.
Open/Closed Principle encourages adding new code instead of changing old code.
This approach makes software easier to maintain and extend.
Practice
Solution
Step 1: Understand the definition of OCP
The Open/Closed Principle states that software components should allow new functionality to be added without changing existing code.Step 2: Match the principle to the options
Software entities should be open for extension but closed for modification correctly states that entities should be open for extension (new features) but closed for modification (existing code remains unchanged).Final Answer:
Software entities should be open for extension but closed for modification. -> Option AQuick Check:
OCP = Open for extension, closed for modification [OK]
- Confusing 'open for extension' with 'open for modification'
- Thinking OCP means rewriting code for new features
- Ignoring the 'closed for modification' part
Solution
Step 1: Identify structures that allow extension without modification
Inheritance and interfaces allow new classes to add behavior without changing existing classes.Step 2: Evaluate options against OCP
Using inheritance or interfaces to add new behavior without changing existing code uses inheritance/interfaces, which aligns with OCP. Other options involve modifying or duplicating code, violating OCP.Final Answer:
Using inheritance or interfaces to add new behavior without changing existing code. -> Option AQuick Check:
Inheritance/interfaces = OCP support [OK]
- Thinking direct modification supports OCP
- Believing code duplication is acceptable
- Ignoring design patterns that enable extension
class Shape {
area() { return 0; }
}
class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}
area() { return this.width * this.height; }
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() { return Math.PI * this.radius * this.radius; }
}
function totalArea(shapes) {
return shapes.reduce((sum, shape) => sum + shape.area(), 0);
}What principle does this design demonstrate?
Solution
Step 1: Analyze how new shapes are added
New shape classes (Rectangle, Circle) extend Shape and implement area(). totalArea works without changes.Step 2: Match design to OCP
Since totalArea does not change when new shapes are added, the design follows Open/Closed Principle.Final Answer:
Open/Closed Principle by allowing new shapes without modifying totalArea. -> Option DQuick Check:
Adding shapes without changing totalArea = OCP [OK]
- Confusing OCP with other SOLID principles
- Thinking totalArea must change for new shapes
- Ignoring inheritance usage
class Report {
generate(type) {
if (type === 'pdf') {
// generate PDF
} else if (type === 'html') {
// generate HTML
}
}
}What is the best fix to comply with OCP?
Solution
Step 1: Identify why current code violates OCP
Adding new report types requires modifying generate() method, breaking OCP.Step 2: Choose design that allows extension without modification
Separate classes for each report type implementing a common interface allow adding new types without changing existing code.Final Answer:
Create separate classes for each report type implementing a common interface. -> Option BQuick Check:
Separate classes = extend without modify [OK]
- Adding more if-else blocks inside methods
- Ignoring interface or inheritance use
- Using global variables for behavior control
Solution
Step 1: Understand the requirement for extensibility without modification
The system must allow adding new payment methods without changing existing code.Step 2: Evaluate design options for OCP compliance
Implementing a Payment interface and creating new classes for each method allows extension by adding classes, not modifying existing ones.Final Answer:
Implement a Payment interface and create new classes for each payment method. -> Option CQuick Check:
Interface + new classes = OCP compliance [OK]
- Using switch statements that require modification
- Rewriting existing code repeatedly
- Using global flags for behavior control
Ready to prove it?
Pass the test and this pattern moves unknown
