Open/Closed Principle (OCP)

This is the ‘O’ in SOLID

Simply put:

  • Open to extension is to allow new behavior to be added in the future
  • Closed to modification is not to change the source/binary code

Definition

“*The Open / Closed Principle states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.*” – Wikipedia

  • Dr. Bertrand Meyer originated the term in his 1988 book, Object-Oriented Software Construction

How do we open things for extension?

The key is to rely on abstractions, so this is interfaces or an abstract base class. Its however very important not to simply apply OCP to every class unless you know based that the business rules are likely to change.

Its best to focus on “Refactoring to a better design”, this means you should write your code with the least amount of complexity first and when needed refactor it and apply a principal such as OCP. So if it changes once, accept it. If it changes again consider refactoring.

PROS

  • Existing core classes are not changed so you are less likely to introduce regression bugs
  • You are adding new classes each time, so you can test and have faith you will not upset things

CONS

  • This add complexity and must be used with caution, dont use OCP to try impress your boss

Typical Approaches

  • Parameters
    • By passing parameters to your methods you allow their behavior to change.
  • Inheritance
    • By using the override keyword in a concrete class you can over-ride the behavior of virtual or abstract methods.
  • Composition / Dependency Injection
    • By injecting an instance of a service defined by its interface the consumer is open to extension but closed for modification.
    • An Abstract Factory can ne used if there are different rules the consumer must follow based on its state. An example is shopping cart price rules.

Sample Code

Shopping cart examples based on work from Steve Smith

Great examples by Steve Smith aka Ardalis

Other Examples from Brad Vincent

References