0
0
LLDsystem_design~15 mins

Open/Closed Principle in LLD - Deep Dive

Choose your learning style9 modes available
Overview - Open/Closed Principle
What is it?
The Open/Closed Principle is a design guideline that says software entities like classes, modules, or functions should be open for extension but closed for modification. This means you can add new features without changing existing code. It helps keep software stable and easier to maintain.
Why it matters
Without this principle, every time you add a new feature, you risk breaking existing code. This leads to bugs, longer development times, and frustrated users. Following it makes software more reliable and adaptable to change, which is crucial in real-world projects where requirements evolve.
Where it fits
Before learning this, you should understand basic programming concepts like classes and functions. After this, you can explore other design principles like Single Responsibility Principle and Dependency Inversion Principle to build clean, maintainable systems.
Mental Model
Core Idea
Design software so you can add new features without changing existing code.
Think of it like...
It's like building a LEGO set where you can add new blocks without breaking apart the existing structure.
┌─────────────────────────────┐
│ Existing Code (Closed)       │
│ ┌─────────────────────────┐ │
│ │ Extension Points (Open) │ │
│ └─────────────────────────┘ │
└─────────────────────────────┘
          ↑
          │
    Add new features here
    without changing above
Build-Up - 6 Steps
1
FoundationUnderstanding Software Change
🤔
Concept: Software often needs new features, but changing existing code can cause bugs.
When developers add new features by modifying existing code, they risk introducing errors. This makes software fragile and hard to maintain over time.
Result
Recognizing that changing code frequently leads to problems sets the stage for better design.
Understanding that change is risky motivates designing software that minimizes modifications.
2
FoundationWhat Open/Closed Means Simply
🤔
Concept: Open means you can add new things; closed means you don't change what already works.
Imagine a book where you can add new chapters without rewriting old ones. Similarly, software should allow adding new features without changing existing code.
Result
You grasp the basic idea that software should be extendable without being altered.
Knowing this simple meaning helps you spot when code violates the principle.
3
IntermediateUsing Abstraction for Extension
🤔Before reading on: do you think adding new features requires changing existing classes or creating new ones that fit existing interfaces? Commit to your answer.
Concept: Abstraction lets you add new behaviors by creating new classes that follow existing interfaces.
By defining interfaces or abstract classes, you can write new classes that add features without touching old code. For example, a payment system can add new payment methods by implementing a common interface.
Result
You can extend functionality by adding new classes, keeping old code untouched.
Understanding abstraction is key to applying the Open/Closed Principle effectively.
4
IntermediatePolymorphism Enables Flexibility
🤔Before reading on: do you think polymorphism helps in adding new features without modifying existing code? Commit to yes or no.
Concept: Polymorphism allows objects to be treated as instances of their interface, enabling new behaviors to plug in seamlessly.
When code uses interfaces or base classes, it can work with any new subclass without changes. This lets you add new behaviors by creating new subclasses.
Result
Your system can handle new feature types dynamically without code changes.
Knowing how polymorphism supports extension without modification deepens your design skills.
5
AdvancedApplying Open/Closed in Real Systems
🤔Before reading on: do you think following Open/Closed Principle always makes code simpler? Commit to yes or no.
Concept: In real projects, Open/Closed Principle guides structuring code with plugins, strategies, or configuration to add features safely.
For example, a logging system might support new log formats by adding new classes without changing core code. This often involves design patterns like Strategy or Decorator.
Result
You see how Open/Closed Principle shapes maintainable, scalable software architectures.
Understanding practical patterns helps you apply the principle without overcomplicating code.
6
ExpertBalancing Open/Closed with Complexity
🤔Before reading on: do you think strictly following Open/Closed Principle can sometimes lead to unnecessary complexity? Commit to yes or no.
Concept: While Open/Closed Principle improves flexibility, overusing abstractions can make code harder to understand and maintain.
Experts balance extension and simplicity by applying the principle where it adds real value, avoiding premature abstraction. They also use tools like feature toggles or modular design.
Result
You learn to apply the principle wisely, avoiding common pitfalls of over-engineering.
Knowing when to apply Open/Closed Principle prevents creating overly complex systems that are hard to maintain.
Under the Hood
The principle works by separating stable code from changeable parts using interfaces or abstract classes. The stable code depends on abstractions, not concrete implementations. New features come as new implementations plugged into these abstractions, so existing code remains untouched.
Why designed this way?
It was created to reduce bugs and maintenance costs caused by changing working code. Early software suffered from fragile designs where small changes broke many parts. This principle encourages designs that isolate change, making software more robust and adaptable.
┌───────────────┐      ┌───────────────┐
│ Stable Code   │─────▶│ Interface /   │
│ (Closed)      │      │ Abstract Base │
└───────────────┘      └───────────────┘
                             ▲
                             │
           ┌─────────────┬─────────────┬─────────────┐
           │             │             │             │
     ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐
     │Feature A│   │Feature B│   │Feature C│   │Feature N│
     └─────────┘   └─────────┘   └─────────┘   └─────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Open/Closed Principle mean never changing any code after first writing it? Commit to yes or no.
Common Belief:Open/Closed Principle means you should never modify existing code once written.
Tap to reveal reality
Reality:It means you should avoid changing existing code to add features, but bug fixes or improvements may still require changes.
Why it matters:Believing you must never change code can lead to ignoring necessary fixes or improvements, harming software quality.
Quick: Does applying Open/Closed Principle always make code simpler? Commit to yes or no.
Common Belief:Following Open/Closed Principle always simplifies code and design.
Tap to reveal reality
Reality:Sometimes it adds layers of abstraction that increase complexity if applied without care.
Why it matters:Misapplying the principle can create confusing code that is hard to understand and maintain.
Quick: Is inheritance the only way to follow Open/Closed Principle? Commit to yes or no.
Common Belief:You must use inheritance to extend behavior and follow Open/Closed Principle.
Tap to reveal reality
Reality:Composition and delegation are often better ways to extend behavior without modifying code.
Why it matters:Relying only on inheritance can cause rigid designs and tight coupling.
Quick: Does Open/Closed Principle mean you should avoid adding new code? Commit to yes or no.
Common Belief:Open/Closed Principle discourages adding new code to avoid changes.
Tap to reveal reality
Reality:It encourages adding new code (extensions) rather than changing existing code.
Why it matters:Misunderstanding this leads to fear of adding features, blocking progress.
Expert Zone
1
Applying Open/Closed Principle often requires careful interface design to avoid frequent changes to abstractions themselves.
2
Balancing between too many small extensions and too few large ones is key to maintainable design.
3
Using feature toggles or configuration can complement Open/Closed Principle by enabling runtime extension without code changes.
When NOT to use
Avoid strict Open/Closed Principle in small or simple projects where added abstraction overhead outweighs benefits. Instead, prefer straightforward code. Also, when requirements are stable and unlikely to change, simpler designs are better.
Production Patterns
Common patterns include Strategy, Decorator, and Plugin architectures that allow adding new behaviors by creating new classes or modules without modifying core code.
Connections
Single Responsibility Principle
Builds-on
Understanding that each module should have one reason to change helps create stable abstractions that Open/Closed Principle depends on.
Modular Design
Same pattern
Both promote dividing software into independent parts that can evolve separately, improving maintainability.
Biological Evolution
Analogy in nature
Just like species evolve by adding new traits without rewriting existing DNA, software evolves by extending behavior without changing stable code.
Common Pitfalls
#1Changing existing classes to add new features.
Wrong approach:class PaymentProcessor { void processCreditCard() { ... } void processPaypal() { ... } // Added later by modifying class }
Correct approach:interface PaymentMethod { void processPayment(); } class CreditCardPayment implements PaymentMethod { ... } class PaypalPayment implements PaymentMethod { ... }
Root cause:Not using abstraction to separate stable code from extensions.
#2Creating too many small classes for every tiny feature.
Wrong approach:class FeatureA implements Interface {} class FeatureB implements Interface {} class FeatureC implements Interface {} // Each feature is a separate class even if trivial
Correct approach:Group related features logically and avoid unnecessary abstractions until needed.
Root cause:Misunderstanding that Open/Closed Principle means always creating new classes, leading to over-engineering.
#3Modifying interfaces frequently to add new methods.
Wrong approach:interface Shape { void draw(); void resize(); // Added later breaks existing implementations }
Correct approach:Use interface segregation: split interfaces so changes don't affect all implementations.
Root cause:Not designing stable abstractions upfront.
Key Takeaways
Open/Closed Principle means design software so you can add new features without changing existing code.
Using abstraction and polymorphism allows new behaviors to plug in safely, keeping code stable.
Overusing abstractions can add complexity, so apply the principle wisely where it adds real value.
Misunderstanding the principle can lead to fragile code or over-engineered designs.
Balancing extension and simplicity is key to maintainable, scalable software.