Open/Closed Principle Explained with Java Example
Learn how the Open/Closed Principle helps write flexible Java code. Follow a real-world example to understand how to extend code without changing it.
Open Closed Principle (OCP)

The O in the SOLID principles stands for the Open Closed Principle (OCP). By the end of this chapter, you'll be able to confidently answer:
-
What is the Open Closed Principle?
-
Why do we need it? (What problems arise if we don’t follow it?)
-
How do we apply it in real-world code?
What is the Open Closed Principle?
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
At first glance, this statement can feel a bit confusing, so let’s break it down.
-
Open for extension: You should be able to add new behavior without changing existing code.
-
Closed for modification: Once your code is working, you shouldn’t have to touch or change it just to add new features.
Why do we need it?
Let’s understand the problem with a real-world example where this principle is not followed.
Here’s the issue with this design:
Every time we want to support a new payment method (e.g., Stripe, PhonePe, Apple Pay, etc.), we need to modify the Payment class and update the if-else or switch block.
What Problems Can This Cause?
-
Risk of breaking existing code: There’s a popular saying — “If it works, don’t touch it.” Modifying working logic just to add something new increases the chance of introducing bugs in existing methods.
-
Tightly coupled logic: All payment methods are tightly bundled together. A change in one area can accidentally impact others.
-
Not scalable: Imagine supporting 10+ payment methods — this class will become a huge mess of conditionals.
-
Poor maintainability: If two developers try to add two new payment types at the same time, merge conflicts are very likely.
But does this mean we should never add new features? Of course not.
What we need is a better design — one that lets us add new payment methods without modifying the core Payment class.
That’s exactly what the Open Closed Principle helps us achieve and we’ll see how in the next section.
How to Achieve the Open Closed Principle
To follow the Open/Closed Principle, we can refactor our code using polymorphism. This allows us to add new payment methods without touching the existing code.
In simpler terms, we’ll create a PaymentMethod interface with a pay() method. Each payment method (like PayPal or Stripe Pay) will have its own class that implements this interface.
Now, if we want to introduce a new payment method (say, GooglePay), we can simply create a new class — no need to modify the core logic.

Benefits of This Approach
-
Easily extendable: Adding a new payment method means adding a new class - no touching old code.
-
No side effects: Existing payment flows won’t break.
-
Cleaner codebase: Each payment method has its own class — easy to manage and test.
-
Follows OCP perfectly: We're extending behavior without modifying what's already working.