What does it mean for a class to be open for extension and closed for modification, and how do you add behaviour without editing existing code?
Open for extension means you can add new behaviour by adding new code. Closed for modification means you do not have to change code that already works. The two together are what let a system absorb new requirements without a cascade of edits through code that was previously correct.
public class Main {
public static void main(String[] args) {
Order order = new Order();
order.add(new Line("Book", 20.0));
order.add(new Line("Pen", 5.0));
System.out.println(order.total(new NoDiscount()));
System.out.println(order.total(new HalfPrice()));
}
}
interface Discount {
double apply(double amount);
}
class NoDiscount implements Discount {
public double apply(double amount) { return amount; }
}
class HalfPrice implements Discount {
public double apply(double amount) { return amount / 2; }
}
class Line {
final String product;
final double price;
Line(String product, double price) { this.product = product; this.price = price; }
double price() { return price; }
}
class Order {
private final java.util.List<Line> lines = new java.util.ArrayList<>();
void add(Line l) { lines.add(l); }
double total(Discount discount) {
double sum = 0;
for (Line l : lines) { sum += l.price(); }
return discount.apply(sum);
}
}The order class is the fixed part. It knows how to total a basket and nothing about the kinds of discount that exist. The discount strategy is what varies, and each variation is a new class that implements the contract. The output shows the same order priced two different ways, and adding a loyalty discount or a bulk discount later would be another class, with no edit to the order at all.
That is the mechanism the principle is really describing: extension happens through new types that fit an existing contract, and the modification happens only in the new type. The code that was correct yesterday is untouched.
Two honest caveats. The principle only works when there is a stable contract to extend, and the more variants you have, the more the strategy mechanism has to be paid for in indirection. And there are places where modification is genuinely the right answer, such as a small set of well-understood branches where a new case is clearly a case of the same thing. The principle is a guideline about where the pressure to change should land, not a law.