Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Open Closed Principle

Design software entities to be open for extension but closed for modification.

The Open Closed Principle (also known as OCP or OCP principle) is one of the five SOLID principles of object-oriented design. The Open Closed Principle (sometimes written as open-closed principle or open/closed principle) states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means you should be able to add new functionality without changing existing code.

In simple terms, whenever we design a class, we need to carefully encapsulate the implementation details so that it has good maintainability. We want it to be open to extension but closed to modification. Understanding the Open Closed Principle is essential for building maintainable, scalable software systems.

Let’s look at a practical Open Closed Principle example to understand how it works in real-world scenarios.

Diagram

The behavior of a module can be extended without modifying its source code. This is typically achieved through mechanisms such as:

Consider a notification system where you need to send alerts through different channels. Instead of modifying the core notification logic every time you add a new channel, you can extend it through inheritance.

Diagram
Diagram

If you need to add a new notification channel (like Teams or SMS), you can create a new subclass without touching the existing code:

classDiagram
    class Notification {
        <<abstract>>
        +send(message: str)
    }
    
    class EmailNotification {
        -recipient: str
        +send(message: str)
    }
    
    class SlackNotification {
        -channel: str
        +send(message: str)
    }
    
    class TeamsNotification {
        -team: str
        +send(message: str)
    }
    
    Notification <|-- EmailNotification
    Notification <|-- SlackNotification
    Notification <|-- TeamsNotification

Handling Scenarios Where Modification Might Be Necessary

Section titled “Handling Scenarios Where Modification Might Be Necessary”

While OCP encourages extension over modification, there are scenarios where modification is unavoidable or where alternative approaches are needed:

When working with external libraries or sealed classes that cannot be extended, use composition and adapters instead.

Problem: You’re using a third-party notification library that you cannot modify:

Solution: Create an adapter/wrapper class that implements your interface:

This way, you extend functionality (add new notification types) without modifying the third-party code, following OCP through composition.

classDiagram
    class Notification {
        <<interface>>
        +send(message: str)
    }
    
    class ThirdPartyEmailService {
        +send_email(to, subject, body)
    }
    
    class ThirdPartyEmailAdapter {
        -email_service: ThirdPartyEmailService
        -recipient: str
        +send(message: str)
    }
    
    Notification <|.. ThirdPartyEmailAdapter
    ThirdPartyEmailAdapter *-- ThirdPartyEmailService : uses

When you need to add functionality that doesn’t belong to the same domain (like logging, caching, or security), consider using decorators or aspect-oriented programming instead of modifying the base class.

Example: Adding audit logging without modifying the base class:

If the core behavior needs to change (not just extend), modification might be necessary. However, consider if this indicates a design issue that should be refactored. Sometimes, it’s better to create a new abstraction rather than modifying the existing one.

💡 Time to Practice!

Now that you understand the concepts, put them into practice with our interactive playground. Build UML diagrams, write code, and get AI-powered feedback.

Browse All Problems