Open/Closed Principle
Open for extension, closed for modification.
The violation
A quote calculator with a switch that must be reopened for every new shipping option:
BigDecimal costFor(String type, BigDecimal total) {
return switch (type) {
case "standard" -> ...;
case "express" -> ...;
// international launch? edit this method, re-test everything it quotes
default -> throw new IllegalArgumentException(type);
};
}
Every new option modifies (and re-risks) tested code, and the calculator accumulates knowledge of every shipping deal the shop has ever offered.
The fix
ShippingQuotes is closed: it quotes whatever ShippingRate
implementations it’s given – StandardShipping and
ExpressShipping here – and is never edited again. The system is open:
launching international delivery means adding one new class and registering it.
Benefits
- New behaviour without touching tested code – the risk of a new shipping option is confined to the new class.
- Deployment-time flexibility – which rates are on offer is decided where the list is assembled, not hard-coded in logic.
- Scales with the business – ten more shipping deals is ten small classes, not a 200-line switch.
Relationship to Strategy
The Strategy pattern is the mechanism that makes this possible; OCP is the principle it serves. Most OCP-compliant designs are built from Strategy-shaped extension points.