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.
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.
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 resultAdvanced 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.
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."