top of page
Programming Console

Need to Extend, Not Rewrite: Why OCP Saves Your Sanity

  • Writer: Maryanne
    Maryanne
  • Apr 10
  • 2 min read

Updated: May 4

Ever added a new feature and accidentally broke the thing that was already working? Yeah, me too. That's what happens when our code isn't built to grow.


 What Is the Open/Closed Principle?

"Software entities should be open for extension, but closed for modification." — Bertrand Meyer
  • Open to extension → Add new features without changing existing code.

  • Closed to modification → Don't touch old code that already works.


Why it matters:

  • Reduces risk of regressions

  • Makes code more testable and maintainable

  • Encourages clean separation of concerns

"Think of your code like a power strip. You don’t open it up every time you want to plug in a new device you just use the extra outlets. OCP is the same: design your code so you can add new behaviors without modifying the core."

The Anti-Example: Code That Violates OCP

public class NotificationService 
{ 
    public void Send(string message, string type) 
    { 
        if (type.Equals("email")) 
        { 
            // send email 
        } 
        else if (type.Equals("sms")) 
        { 
            // send SMS 
        } 
    } 
}

What’s wrong?

  • Every time a new type is added (Slack, Teams, Push), the class needs to be edited.

  • This violates Open/Closed.

  • It breaks encapsulation and risks bugs.


The Fix: Open for Extension, Closed for Modification

Step 1: Use an interface to abstract the behavior

public interface INotifier 
{ 
void Send(string message); 
}

Step 2: Create extensible implementations

public class EmailNotifier : INotifier 
{ 
    public void Send(string message) 
    { 
        // Send email logic 
    } 
}
public class SmsNotifier : INotifier 
{ 
    public void Send(string message) 
    { 
        // Send SMS logic 
    } 
}

Step 3: Inject behavior into the service

public class NotificationService 
{ 
    private readonly INotifier notifier; 

    public NotificationService(INotifier notifier) 
    { 
        this.notifier = notifier; 
    } 
    public void Notify(string message) 
    { 
        notifier.Send(message); 
    } 
}    

Now want to add Slack? Just make a new SlackNotifier class no changes to NotificationService needed.

Boom. 🎤 Drop.

Real-World Use Cases

  • Payment processors (Stripe, PayPal, etc.)

  • Shipping methods

  • Authentication strategies

  • Game AI behaviors

  • Logging providers

Common Pitfalls

  • Overengineering: Don’t abstract everything. Only apply OCP when it solves a real problem.

  • Forgetting to use dependency injection.

  • Tightly coupling your "extension" logic.

Key Takeaways

  • OCP helps your code scale without becoming spaghetti.

  • Use interfaces or base classes to allow extension.

  • Keep your core logic stable and isolated.

  • Think plugins, not patches.

“Code is like Lego. If you have to glue the bricks to make them stick, you’re doing it wrong.”

A Developer building legos

Want to share one of your Bad Blocks? Would love to hear about it


Comentarios


bottom of page