Open Closed Principle

open closed principle

The Open Closed Principle is another concept in our study of the solid design approaches in the object oriented style. You may have heard the idea that code should be open for extension but closed for modification. Ok. Really what this means is that when writing code, we should aim for the ability to change behavior without having to actually change the code. Another way of saying this is to program in a way so that the code does not need to be changed each time the requirements of the project change. Like most things solid, it sounds great, and is far easier said than done. It is a worthy principle to investigate however.

No Area Calculations

Pretty much every tutorial under the sun uses the example of calculating the area of different shapes to illustrate the open closed principle. Let’s not do that. We need to create something from our imagination if we really want the concept to stick. We will take the concept of delivering Pizzas. Sounds much more fun than calculating the area of shapes. Instead of dealing with how to calculate an area, we’ll work on how to deliver a Pizza. As such, we need a PizzaDelivery class.

Here we have a perfectly good class that is able to deliver Pizza in a fine manner. It turns out however, that your Pizza Job is going above and beyond. Not only will they drive pizza across town, if a customer lives on an island, this Pizza Restaurant will Bring it to them right across the water. Now you are the Pizza delivery guy. Is your deliver method going to work right when you need to travel by water? It might go something like this.

Breaking The OCP

Fair enough, we can fix this. Let’s just change our code to allow for delivering Pizza by boat.

Nice! Just like that, you are now able to deliver Pizza by boat! You got the Pizza to the customer on time, she was so thrilled that she invited you in to watch Breaking Bad. Before you go popping the champagne however, you need to know, you just broke the open closed principle. How so? Well, when your Pizza shop decided to implement a new behavior, you had to go back and change the original code to fit that need. In addition, the dead ringer here is that you are doing type checking inside the class to decide which behavior to take. Our PizzaDelivery class should be able to simply call a deliver method, and get the job done, whether by Car, Boat, or Plane! Let’s clean things up (or dry up, make solid, remove smell, whatever you want to call it). Our goal is to simply have a method call something like this:

and our Pizza will be delivered, no matter how or where it gets delivered to. We can do this!

So what did we do here? We removed the need to do type checking inside our PizzaDelivery class. By doing so, we can change behaviors in the application, without touching the code. We are following the convention of closed for modification and open for extension. Here is the process we followed to achieve this.

  • Extract the behavior for the deliver() method out of the PizzaDelivery class
  • Create an interface Deliverable which defines the contract for delivery
  • Create new classes as needed that implement the interface to add behavior

Open For Extension

Our code is now open for extension! To prove this, we have decided that we will now offer the ability to deliver Pizza to the moon! Watch us add this behavior without ever touching the PizzaDelivery class.

Add (do not modify!) to the codebase

Observe success of new code

With our interface in place, we were able to leave our PizzaDelivery class, as well as our client code, untouched. All we had to do was add a new Spaceship class and have it implement our Deliverable interface. Done. 🙂