☺

JB's Blog

β€”

LifeStyle | Coding | Creativity

Open/Closed Principle in Software Design

β€”

by

in


The Open/Closed Principle (OCP) is the “O” in SOLID, and a critical principle for designing flexible, scalable, and future-proof systems. In this article, we will cover OCP from basic theory to advanced practical applications across backend systems, frontend interfaces, testing strategies, and real-world architecture.


πŸ’‘ What is the Open/Closed Principle (OCP)?

β€œSoftware entities (classes, modules, functions) should be open for extension but closed for modification.” β€” Bertrand Meyer

This means we should be able to add new behavior to our systems without modifying existing tested code.

βœ… Extend = Add new code.
βœ… Closed = Do not touch old working code.


🎬 Visual Metaphor: Smart City Transport

You have a smart city controlling cars and buses. Tomorrow, drones need to be integrated.

βœ… If you designed transport rules via interfaces, you can plug in drones easily.
❌ If rules are hardcoded for only cars and buses, you must rewrite logic = risk of bugs.


πŸ”¨ Code-Level Application: Replacing Switches with Strategies

❌ Violation:

if (paymentType.equals("UPI")) handleUPI();
else if (paymentType.equals("CARD")) handleCard();

βœ… OCP Fix (Strategy Pattern):

interface PaymentStrategy { String getType(); void pay(); }
class UpiPayment implements PaymentStrategy { ... }
class CardPayment implements PaymentStrategy { ... }

Inject via Spring Boot:

Map<String, PaymentStrategy> strategies;
strategies.get(type).pay();

No switch-case modification. Just new strategies plugged in.


βš™οΈ OCP in Spring Boot

Interface:

public interface NotificationChannel {
    String getType();
    void send(Message msg);
}

Components:

@Component
public class EmailChannel implements NotificationChannel { ... }

Service Injection:

@Autowired
public NotificationService(List<NotificationChannel> channels) {
    for (var c : channels) map.put(c.getType(), c);
}

βœ… New channels auto-discovered without modifying existing NotificationService.


πŸ§ͺ Testing OCP-Compliant Code

  • Strategies tested independently.
  • Core service doesn’t require modification/testing if new behavior is added.
@Test void testEmailChannel() { emailChannel.send(message); }
@Test void testServiceDelegation() { notificationService.send("email", message); }

🧩 Real-World Violations and Their OCP Fixes

ViolationFix
switch(user.role)RoleHandler strategy map
if (reportType == ...)ReportGenerator strategy interface
Feature flags inside business logicFeatureStrategy plugins
DTO mapping with instanceof chainsFormatter pattern

🌐 OCP in Frontend (React/Angular)

FeatureOCP Strategy
Dynamic FormsSchema-driven FieldType β†’ Component Map
Theme SwitchingAbstract tokens with ThemeProvider
Dashboard WidgetsType β†’ Component plugin map
const FieldTypeMap = {
  text: TextInput,
  select: SelectBox,
  date: DatePicker,
};

βœ… Add new field types without modifying core form renderer.


🌐 OCP in API Layer (Spring Boot)

API Use CaseOCP Strategy
API VersioningVersionHandler strategy map
Content NegotiationContentSerializer per format
Field Projection (GraphQL)Transformer per DTO/field set
Export Files (PDF/CSV)Exporter strategy loader
interface ContentSerializer {
    boolean supports(String type);
    String serialize(Object obj);
}

βœ… Adding new formats/extensions without touching controllers.


⚠️ Drawbacks and Overuse of OCP

SymptomRisk
Too many tiny classesClass explosion
Premature abstractionAdded complexity with no real need
Debugging difficultyTraceability issues
Interface fatigueAbstracting non-volatile parts unnecessarily

βœ… Tip: Only apply OCP when volatility is observed or anticipated realistically.


βœ… Summary: Ways to Apply OCP

πŸ” In Code

  • Interfaces + Polymorphism
  • Strategy Pattern, Command Pattern
  • Spring Boot’s List<Interface> injection
  • Handler maps for resolution

🌐 In API

  • API version handlers
  • Content serializers
  • DTO transformers
  • Exporter strategies

πŸ’» In Frontend

  • Schema-driven form renderers
  • Theming providers
  • Widget/plugin component maps

βœ… Apply OCP mindfully, not mindlessly.


πŸ” Final Reflection

The Open/Closed Principle helps you:

  • Roll out new features faster
  • Maintain stable tested bases
  • Empower plugins, modules, extensions
  • Reduce regression risk dramatically

Good software grows by extension, not mutation.



Leave a comment