GetNoticed IT#5: S-Open/Closed Principle-L-I-D

Good evening!
The time is high to write new post. I’m continuing about SOLID principles. Today it’s “O” which stands for Open/Closed Principle. According to Wikipedia this rule was first defined by Bertrand Meyer in his book Object-Oriented Software Construction (1988). The rule states:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Or as others say:

Once a class is done, it’s done!

The idea behind those statements is that if we have a class and it is needed to extend it or modify we create new class which inherits either from our existing class (with use of overridden methods) or from abstractions.
Seems pretty easy, right? However, I still had a bit of a struggle to figure it out and comprehend it in my own way. It would be the best if I explain it on an example. My project for GetNoticed2017 contest is based on rectangles so let us consider an example with rectangles.

Our program has to perform some simple transformations of a rectangle. In order to do that we have a static Transformations class which consist of two methods that take a rectangle as an argument and return transformed one.

Currently our Transformations class can only rotate a rectangle by 90 degrees and scale it. And that would work perfectly fine up to the point where we want to add new transformation. In order to do that we need to modify Transormations class and that is clearly violation of OCP.
Let’s now rebuild our little system to be consistent with OCP. Key to that is abstraction – in our case that simple interface:

Now, we’re going to write separate classes for our two methods we’ve already had in Transformations class.

So, now we have everything we had before but the difference is that we now follow the OCP. Of course, way of use of these classes will be different that one static class. Let me show you that using unit tests:

As you can see our test class has a field of type ITransform which holds objects of our new transformation classes. Changing value of it we can freely shuffle with what operation we can perform (for example, instances can be supplied by an IoC container).
At this point adding new transformation is quite easy. But let’s introduce another type of transformation just for its own sake. Let it be cutting in half along vertical axis:

And that’s it. Open/Closed principle is followed. At this point you may ask question why. The example presented here is very simple, not to say primitive. But in real world classes are bigger and a little bit more complicated. So once a class is tested and running in production environment any change may inflict a bug. Not changing existing classes eliminates that risk. Obviously you can create a bug in your new class (inheriting from an existing class or from interface) but that is yet to be tested. There is no risk that you could break already tested and working code.

As a conclusion to this post and two previous related to SOLID I have one observation: ABSTRACTIONS are extremely important and useful.

Source code for this example:

Here are some more examples of how to follow the open/closed principle:

Links to my previous posts related to SOLID:
#1: Dependency Inversion Principle
#2: Single Responsibility Principle

Hope you’ve enjoyed reading this post and it will be somehow useful for you.
Good luck!