Mastering Open/Closed Principle (OCP) in Salesforce with Real Examples

May 26, 2026
5 Views
Mastering Open/Closed Principle (OCP) in Salesforce with Real Examples
Summarize this blog post with:

When developers first start working on Salesforce projects, they usually focus on making the code. And honestly, that is too normal. If the feature is running correctly, it feels like the job is done for the day.

But after some time, real problems begin to appear, when a client asks for a small change and you have to update one Apex class. Suddenly, another feature stops working and then another fix is needed. And slowly, one simple class becomes a big mess full of conditions, edits, and confusing logic.

This is exactly where the Open/Closed Principle (OCP) feels like a life saver. In this detailed guide, we’ll understand: What OCP is and How it works, 4 key benefits for Salesforce teams, how to implement it step by step with Apex code.

What is the Open/Closed Principle?

The Open and Closed Principle is one out of five foundational design rules, which is identical as SOLID. Here, each letter in SOLID stands for one principle, and “O” is OCP. Here is the full set so you get to know where it fits:

S     Single ResponsibilityO Open/Closed

L     Liskov Substitution

I      Interface Segregation

D    Dependency Inversion

There is a definition, given by Bertrand Meyer and popularized by Robert C. Martin (Uncle Bob) that Software entities should be open for extension, but closed for modification.

Hence you should be able to teach your code new tricks without rewriting the code, which is already working. “Open for extension” means new behavior can be added. “Closed for modification” means the existing, tested code does not need to be touched to do so.

How does OCP work?

Think of a power extension on your desk and you’re gonna plug in a new fan, lamp, or phone charger without ever rewiring the strip itself with the power plug. The strip is open for new devices, but closed, meaning you do not crack it open and solder new wires every time you buy something new.Bad code works like a badly designed stripe every new business type requires opening it up and risk burning the house down. OCP says: design your classes the same way a good power strip is designed.

In Salesforce Apex, OCP is achieved through interfaces and the Strategy Pattern. You define a contract (interface) that all variations must follow, then create a separate class for each variation. The main class only knows the contract, never the specific variations, so adding a new one means writing a new class, not editing an old one.

Every time you see an if-else or switch statement that branches by type, category, or channel, that is the exact spot where OCP applies. New types should come from new classes, not new ones if blocks.

Benefits of OCP in Salesforce

  • Zero regression risk

Existing classes are never touched when new logic is added,
so existing tests never break.

  • Faster development

Creating a new class from scratch is always faster than carefully
editing one that could break unexpectedly.

  • Cleaner unit tests

Each strategy class is small and self-contained. Tests are focused,
fast, and need no complex mocking.

  • Team-friendly

Two developers can build two strategies in parallel with no merge
conflicts on shared files.

How to implement OCP step by step

Let’s understand this with a basic Salesforce scenario, think you have to calculate a discount that currently handles Gold and Silver customers, but the business keeps adding new tiers. Here is the wrong way first, then the right way.

The problem — a class that must be edited every time

// DiscountCalculator.cls — violates OCP

public class DiscountCalculator {
    public Decimal getDiscount(String customerType) {
        if (customerType == 'Gold')     { return 0.20; }
        else if (customerType == 'Silver') { return 0.10; }
        // Every new tier = open this file and risk breaking Gold/Silver
        else { return 0.0; }
    }
}

Every time a new tier arrives, you edit this file. You risk breaking Gold and Silver. You re-deploy everything. This is fragile.

The OCP solution — 4 simple steps

  1. Create an Interface — the shared contractAll discount types will promise to implement this one method. The contract never changes.
  2. Create one class per discount typeEach type lives in its own file. Adding a new type = adding a new file. Nothing else changes.
  3. Make the calculator work with the interface, not the concrete typesThe calculator only knows the contract. It never cares which specific discount type it’s working with.
  4. Pass in the right strategy wherever you need itThe calling code chooses which strategy to inject. The calculator itself stays permanently unchanged.
Step 1 — Define the interface

// IDiscountStrategy.cls
public interface IDiscountStrategy {
    Decimal getDiscount();
}
Step 2 — One class per discount type

// GoldDiscount.cls
public class GoldDiscount implements IDiscountStrategy {
public Decimal getDiscount() { return 0.20; }
}
// SilverDiscount.cls
public class SilverDiscount implements IDiscountStrategy {
public Decimal getDiscount() { return 0.10; }
}
// PlatinumDiscount.cls — added later. Zero changes to the above files.
public class PlatinumDiscount implements IDiscountStrategy {
public Decimal getDiscount() { return 0.25; }
}
Step 3 — Calculator works with the interface only
// DiscountCalculator.cls — closed for modification, forever
public class DiscountCalculator {
public static Decimal calculate(IDiscountStrategy strategy) {
return strategy.getDiscount();
}
}
Step 4 — Usage

// Gold customer
Decimal d = DiscountCalculator.calculate(new GoldDiscount());
// New Diamond VIP tier added later — just one new file, nothing else touched
Decimal vip = DiscountCalculator.calculate(new DiamondDiscount());
What changed?

Adding Diamond VIP required exactly one new file, DiamondDiscount.cls. The calculator, Gold, Silver, and Platinum classes were never opened. Their tests still pass. Nothing was at risk.

Conclusion

In the Solid Principle the O stands for Open/closed function, in salesforce it solves one of the most common issues of the salesforce world. Open/Close principle helps to break the code every time when a business wants to add a new type, tier or any channel.

The formula is straightforward, define an interface, create one class per variation, and let the main class work only with the interface. When the business adds something new, you add a new class. The existing code never changes. The existing tests never fail. Your deployment is predictable and your team sleeps better.

Apply OCP wherever you see type-based if-else chains that are likely to grow. Start simple, then refactor toward it when the second or third type arrives. That’s when it pays for itself, and it keeps paying, for the entire life of the org.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Written by

Mohit Bansal

Salesforce Technical Architect | Lead | Salesforce Lightning & Integrations Expert | Pardot | 5X Salesforce Certified | App Publisher | Blogger

Get the latest tips, news, updates, advice, inspiration, and more….

Contributor of the month
contributor
Antonina Kharchenko

Technical Writer, Salesforce Admin at SFApps.info

...
Categories
...
Boost Your Brand's Visibility

Want to promote your products/services in front of more customers?

...

Leave a Reply

Your email address will not be published. Required fields are marked *