Card 01/ 08

ConceptDifficulty: Beginner2 min

Open/Closed: Add Behaviour Without Editing What Works

A new payment method should be a new class, not a new branch in an old one.

The open/closed principle says that a class should be open for extension but closed for modification. Open for extension means you can make it do new things. Closed for modification means you do that without editing its source. This card explains how both can be true at once, and why it matters for code that already works.

A checkout shows the problem. Its pay method handles cards with an if statement on the payment type. The business adds PayPal, so a developer adds an elif branch to pay. The new branch works, but the edit also moved a variable the card branch used, and card payments fail for an hour on a Saturday. The card code was correct and tested. It broke because the only way to add PayPal was to open the method that held it.

Bertrand Meyer stated the principle in 1988 in "Object-Oriented Software Construction", and his answer was inheritance: extend a finished class with a subclass. Robert C. Martin restated it in 1996 in the form used today. The stable code depends on an abstraction, an interface naming what every case can do, and each case is a separate class that implements it. The interface is the extension point.

A closed Checkout that depends on an extension point

Read the diagram from the top. Checkout knows only PaymentMethod. Adding Apple Pay is a new class beside PayPalPayment, and Checkout and CardPayment are not opened at all. Their tests still pass because nothing in them changed.

A power strip gives the feel of it: a new appliance plugs in without rewiring the house. The analogy breaks in one place. A socket fixes the shape of every plug for good, while an interface can be changed later, but only at the cost of editing every class that implements it. Choosing what the interface asks for is the real design decision.

← → move through sections and cards