O Open Closed Principle OCP

2 min read
Foundational2 min read
Rapid overview

Open Closed Principle (OCP)

TL;DR

The Open/Closed Principle says modules should be open for extension but closed for modification: new behaviour should arrive as new types (strategies, plugins, decorators) rather than edits to battle-tested code. Done well it eliminates the giant switch statements and shotgun changes that turn every new requirement into a regression risk.

How it works

O — Open/Closed Principle (OCP)

“Software entities should be open for extension but closed for modification.”

You should add new behavior without editing existing code.

✅ Example: New trade execution channels

public interface ITradeExecutor
{
    void Execute(Order order);
}

public class Mt4Executor : ITradeExecutor
{
    public void Execute(Order order) => Console.WriteLine("MT4 order executed");
}

public class Mt5Executor : ITradeExecutor
{
    public void Execute(Order order) => Console.WriteLine("MT5 order executed");
}

// Add new platform without touching existing code
public class TradeService
{
    private readonly ITradeExecutor _executor;
    public TradeService(ITradeExecutor executor) => _executor = executor;

    public void Execute(Order order) => _executor.Execute(order);
}

✅ Adding a new trading platform (like cTrader or FIX API) just means creating another ITradeExecutor implementation — no code modification, only extension.


Quick recall Q&A

Q: How do you ensure new features don’t require modifying existing classes?

Depend on abstractions and register new implementations via DI. Use patterns like Strategy or Decorator so new behavior plugs in without touching existing code.

Q: What signals an OCP violation?

If every new platform or workflow requires editing the same switch statement or base class, you’re modifying existing code instead of extending via new types.

Q: How do feature flags interact with OCP?

Feature flags can select between implementations at runtime without modifying code. Register both paths and toggle via configuration, respecting OCP.

Q: How do you balance OCP with readability?

Don’t over-abstract. Introduce extension points only when change pressure exists. Keep base abstractions small so extensions remain straightforward.

Q: How does OCP apply to APIs?

Version APIs instead of changing contracts. Add new endpoints or fields while keeping existing behavior untouched to avoid breaking clients.

Q: What tooling helps enforce OCP?

Architecture tests verifying dependencies, code analyzers warning on large switch statements, and DI/registration conventions that encourage extending via new classes.

Q: How do templates or generics aid OCP?

Generics let you inject behavior (e.g., IRepository<T>) without rewriting code for each type. Base functionality stays closed; new types extend usage.

Q: How do you vet extension points for security/compliance?

Document allowed extensions, run threat modeling on new implementations, and add automated tests to ensure they honor validation/risk rules like existing types.

Q: Can configuration count as “extension”?

If behavior is data-driven (rules engine, config-based workflows), adding entries might be enough. Ensure validation guards keep config changes safe.

Q: How does OCP help with plugin architectures?

Plugins implement known interfaces and register themselves. The host never changes; you drop in new assemblies to extend behavior safely.

See also