SOLID PrinciplesOpen-Closed PrincipleHard⏱️ ~4 min

OCP in Interviews: Common Questions and Variations

Typical Interview Questions

Question 1: "Design a notification system that supports Email, SMS, and Push notifications. How would you apply OCP?"

Answer Approach: Define a NotificationChannel interface with a send(message, recipient) method. Create EmailChannel, SMSChannel, and PushChannel implementations. The NotificationService depends on the abstraction, not concrete channels. To add Slack or WhatsApp notifications later, create new classes without modifying existing code.

Interview Tip: After presenting the design, proactively address follow-up concerns: "If each channel has unique configuration (SMTP server for email, API key for SMS), I would pass these via constructor dependency injection. If message formatting differs, I might introduce a MessageFormatter abstraction as well."

Question 2: "Your current code has a large switch-case on vehicle type in the parking fee calculator. How would you refactor it to follow OCP?"

Answer Approach: First, identify that vehicle type variation is the extension point. Second, extract each case into a separate class implementing FeeCalculationStrategy or make Vehicle an abstract class with a calculateFee() method. Third, replace the switch with polymorphic dispatch. Fourth, explain: "Now, adding a new vehicle type like RV or Bicycle requires only creating a new class, not modifying the calculator."

Machine Coding Considerations

When implementing OCP in timed coding rounds, follow this workflow:

Step 1: Start with the abstraction. Define the interface or abstract class first, even if you only have one concrete implementation initially. This signals OCP intent to the interviewer.

Step 2: Implement one or two concrete classes to prove the abstraction works. Do not create ten implementations; two is enough to demonstrate extensibility.

Step 3: Show client usage. Write code where the client depends on the abstraction (List<DiscountStrategy>, not List<MemberDiscount>). Use polymorphism in a loop or method call.

Step 4: Verbally explain extension: "To add a new discount, I would create CorporateDiscount implementing DiscountStrategy. No other classes change." You do not need to actually code the new class; the explanation suffices.

Code Structure Template:
interface Strategy:
  execute(context): Result

class ConcreteStrategyA implements Strategy:
  execute(context): Result
    // Implementation A

class ConcreteStrategyB implements Strategy:
  execute(context): Result
    // Implementation B

class Client:
  strategy: Strategy
  
  setStrategy(s: Strategy): void
    this.strategy = s
  
  doWork(): void
    result = strategy.execute(context)
    // Use result

Advanced Variations

Combining Strategies: Interviewer asks: "What if multiple discounts apply simultaneously?" Answer: Use the Composite Pattern. Create a CompositeDiscount that holds a list of DiscountStrategy objects and applies them in sequence or selects the best one. This still follows OCP because adding the composite does not modify existing strategies.

Dynamic Extension at Runtime: "How would you allow users to define custom rules without recompiling?" Answer: This requires a Rule Engine or Interpreter Pattern. While OCP applies at the code level, runtime extensibility needs a different mechanism (scripting, DSL, or configuration-driven rule evaluation). Acknowledge that OCP alone does not solve this; you need an execution engine that interprets user-defined rules.

Interface Evolution: "What if the NotificationChannel interface needs a new method for tracking delivery status?" Answer: This violates the "closed" part of OCP. All implementations must change. To mitigate, consider: First, use the Interface Segregation Principle (ISP) to split interfaces by client needs. Second, add default methods (if the language supports them). Third, create a new interface (TrackableChannel) that extends the original, allowing gradual migration. But accept that sometimes the abstraction itself needs evolution, and that is acceptable if it represents a fundamental requirement change.

Interview Tip: When discussing interface evolution, acknowledge the tension: "Ideally, abstractions are stable, but if a core requirement changes, modifying the interface is justified. The key is to minimize such changes by designing the abstraction carefully upfront, focusing on essential operations."

Common Mistakes to Avoid

Mistake 1: Creating God Interfaces. Do not add every possible method to the abstraction. Keep interfaces focused (ISP) so that implementations are not forced to provide empty methods.

Mistake 2: Forgetting Dependency Injection. If the client instantiates concrete classes directly (new CreditCardPayment()), you lose OCP benefits. Use factories, dependency injection, or configuration to provide concrete implementations.

Mistake 3: Not Explaining the "Why." In interviews, stating "This follows OCP" is insufficient. Explain: "By depending on the PaymentMethod abstraction, the PaymentProcessor can support new payment types without modification, reducing regression risk and enabling third-party payment integrations."

💡 Key Takeaways
Start with abstraction in coding rounds, even with one implementation
Demonstrate extensibility by explaining (not coding) how new classes are added
Use Composite Pattern for combining strategies without violating OCP
Acknowledge interface evolution challenges; use ISP to minimize impact
Avoid God Interfaces, ensure dependency injection, and always explain the design rationale
📌 Examples
1Notification system with Email, SMS, Push channels
2Refactoring switch-case on vehicle type to polymorphic strategy
3Combining multiple discount strategies using Composite Pattern
← Back to Open-Closed Principle Overview
OCP in Interviews: Common Questions and Variations | Open-Closed Principle - System Overflow