If-else chains as OCP violations
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
A long if-else or switch is an OCP problem when it acts as a catalogue of behavior variants and must be modified whenever a new variant is added. A shipping calculator that contains all ground, express, and freight algorithms in one switch has that change pattern.
Those algorithms can implement a ShippingCost contract and be selected by a registry or composition root. The calculator then calls the selected handler without knowing its concrete type. A new carrier adds a handler and registration, while existing calculations remain isolated.
The presence of a conditional alone is not a violation. A short switch over a deliberately closed enum, input validation, or explicit state-machine logic may be the simplest and safest design. The signal is repeated change and independent behavior, not a rule that every switch must become classes.
If-else chains as OCP violations
Direct Answer
A long conditional can violate OCP when it repeatedly selects behavior by type and must be edited for every new variant. That is a signal to consider polymorphism, a handler registry, or data-driven rules. Conditionals are not inherently wrong: a small, stable, exhaustive decision can be clearer than an abstraction.
Code Example
// BEFORE: Type-switching antipattern (OCP violation)
class ShippingCalculatorBad {
public double calculateCost(String method, double weight) {
if (method.equals("GROUND")) {
return weight * 1.5;
} else if (method.equals("EXPRESS")) {
return weight * 3.0 + 10;
} else if (method.equals("OVERNIGHT")) {
return weight * 5.0 + 20;
}
throw new IllegalArgumentException("Unknown method: " + method);
// Adding AIR_FREIGHT means modifying this method
}
}
// AFTER: Polymorphic approach (OCP compliant)
interface ShippingMethod {
double calculateCost(double weight);
}
class GroundShipping implements ShippingMethod {
public double calculateCost(double weight) {
return weight * 1.5;
}
}
class ExpressShipping implements ShippingMethod {
public double calculateCost(double weight) {
return weight * 3.0 + 10;
}
}
class OvernightShipping implements ShippingMethod {
public double calculateCost(double weight) {
return weight * 5.0 + 20;
}
}
@Service
class ShippingCalculatorGood {
public double calculateCost(ShippingMethod method, double weight) {
return method.calculateCost(weight); // No if-else needed
}
// Adding AirFreightShipping requires zero changes here
}
Common Mistakes & Pitfalls
- Refactoring every switch into classes: a small closed decision can be clearer as direct control flow.
- Changing syntax without changing the change boundary: replacing
ifwithswitchdoes not isolate independently evolving algorithms. - Creating strategies while retaining concrete type checks in the client: selection belongs at a deliberate boundary.
- Ignoring evidence: use repeated additions, ownership, and branch complexity to justify the abstraction.
Check your understanding
Answer these without looking back at the article.
- What is the type-switching antipattern?
- How do you refactor an if-else chain to be OCP-compliant?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.