# Open-Closed Principle

**In short:** A building block stays open to new behavior but closed to edits of its existing code. Other parts rely on a fixed interface, and new behavior arrives through new implementations of it.

## Explanation

The principle has two halves. A module is **open** if you can still extend it. A module is **closed** if other modules can already use it, because it offers a stable, well-defined interface.

The common slogan says software entities such as classes, modules, and functions should be open for extension but closed for modification. The idea is to add behavior without editing the original code.

**Two readings.** Meyer's 1988 book introduced the principle. His idea was extension by inheriting from existing code without changing it. A later, polymorphic reading keeps the abstract interface fixed. New implementations of that interface supply new behavior, and each must at least implement the interface.

**Plug-ins.** Plug-in style extension relies on inversion of control. Your code plugs something into a framework, and the framework calls it back. The framework stays closed. The plug-in adds behavior.

**Dependency inversion.** The Dependency Inversion Principle is about shape. Abstractions and high-level policy should not depend on low-level details. Depending on an abstraction is what lets the interface stay fixed while implementations change.

**Beyond classes.** The slogan names modules as well as classes. Fowler also notes the same idea in building blocks that are extended to handle new scenarios as a system grows.

## Example

A shop system calculates shipping costs. The checkout component talks only to a "shipping calculator" interface. At first there is one implementation, for standard delivery. Later the shop adds express delivery and pickup. Each is a new implementation of the same interface. The checkout component does not change.

## Trade-offs

Extension points cost effort. An extension point that is never used is wasted work, and it is likely to get in the way. Abstractions that make the code harder to understand for current requirements are suspect. So add openness where change is expected, not everywhere.

Checkout depends on a fixed interface; new delivery options are added as new implementations.

```plantuml
@startuml
interface ShippingCalculator
class Checkout
class StandardDelivery
class ExpressDelivery
class Pickup
Checkout --> ShippingCalculator : uses
StandardDelivery ..|> ShippingCalculator
ExpressDelivery ..|> ShippingCalculator
Pickup ..|> ShippingCalculator
@enduml
```

## Checks

- Components that are expected to change expose a stable, well-defined interface that other components use.
- Extension points exist only where change is expected, and unused extension points are removed.
- New behavior is added through new implementations of an existing interface or through plug-ins, not by editing existing code.

## Related

- [Information Hiding](https://arc.fuet.ch/concepts/principles/information-hiding.md)
- [Design for Change](https://arc.fuet.ch/concepts/principles/design-for-change.md)
- [Modifiability](https://arc.fuet.ch/concepts/quality-attributes/modifiability.md)
- [Loose Coupling](https://arc.fuet.ch/concepts/principles/loose-coupling.md)
- [Microkernel Pattern](https://arc.fuet.ch/concepts/styles-patterns/microkernel-pattern.md)
- [Architecture Principle](https://arc.fuet.ch/concepts/principles/architecture-principle.md)
- [Interface Segregation Principle](https://arc.fuet.ch/concepts/principles/interface-segregation-principle.md)
- [Modifiability Tactic](https://arc.fuet.ch/concepts/tactics/modifiability-tactics.md)

## Sources

- [Open–closed principle - Wikipedia](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle) — en.wikipedia.org, accessed 2026-11-09
- [DIP in the Wild](https://martinfowler.com/articles/dipInTheWild.html) — martinfowler.com, accessed 2026-11-09
- [Yagni](https://martinfowler.com/bliki/Yagni.html) — martinfowler.com, accessed 2026-11-09
