As a software developer, you get used to lots of acronyms being banded about, but perhaps one of the most important is SOLID.In this series of posts, I will endeavour to explain the ideas behind the terminology and why it should be central to everything you do as a software developer.
This post is for the O of Solid
Extend me, don’t change meImagine a world without letterboxes. Imagine a time when you had to leave your front door wide open just in case the post man wanted to deliver a letter. Anyone could come inside, make a mess of your front room, break things and leave! Not good.
Luckily, we don’t live in that sort of a world. If someone wants to send you a letter then the message is posted through your letterbox, then you can read it and choose to respond to the letter without allowing anyone to into your home.
This is what the Open Closed Principle is all about. Uncle Bob says
software entities … should be open for extension, but closed for modification
Let’s return to our Ninja Robot friend RoboSlave and his
MakeBreakfast() method. I mentioned that we may want the option of having RoboSlave serve us toast for breakfast instead of cereal.
We don’t want our uses to have to start changing the code in order to make RoboSlave provide their preferred type of breakfast, what we’d really like is to be able to modify the behaviour of the
MakeBreakfast() method without changing any code.
Instead we could pass in a parameter for the type of breakfast we require and RoboSlave would respond accordingly. The Method would look like
MakeBreakfast(BreakfastChoice choice) where BreakfastChoice is a list of options such as Toast, Cereal, BaconAndEggs, Croissant etc) but that would soon become very messy and hard to test.
Even better, instead of having one MakeBreakfast method, we could have separate classes that all provide their own version of the MakeBreakfast method and when we run the RoboSlave program, we could choose which version of the class we want to program RoboSlave with. This way we can add additional implementations as we familiarise ourselves with breakfasts of the world! Mmmmmm, pancakes!
Now we’d have an interface called
IMakeBreakfast that promises that any other class that implements
IMakeBreakfast will provide a method called
MakeBreakfast(). Each of these classes can implement the method in very different ways, you may want a poached egg, a scrambled egg or even a fried egg but all RoboSlave cares about is that it knows you will provide a class that can tell RoboSlave how you like it.
Another benefit of this approach is that we can safely add a new implementation of
IMakeBreakfast with the comfort of knowing that we’re not breaking any of the other versions of the class. Mr Crumpet will still get his bit of Crumpet and Mr Toast will still get his warm bread with lashings of marmalade.
In the next post we will explore the Liskov Substitution Principle