The importance of the Open Closed principle and the Specification Pattern.

Lehlohonolo Isaac
DVT Software Engineering
4 min readMay 3, 2018

--

Lehlohonolo Isaac, iOS Developer, DVT

Photo by Thanos Pal on Unsplash

Have you ever had to rewrite the same function over and over again that was doing the same thing? Let’s say, as an example; you wanted to filter a list of Vehicles by type, colour and price.

How I’d go about implementing this is by writing three functions for filtering, although with different specification. Thus, these three functions will only differ by their specification even though they do the same thing, which is filtering a list of vehicles.

The simple way of solving this problem is by injecting a specification inside a filter. In this case, we will have only one filter. In order for us to filter by colour, we will inject a Color Specification. To filter by type, we will inject a Vehicle Type Specification, and so on. Now we will only be having one Filter for our application.

Let’s take a look at what happens if you do not use the Specification pattern for the above example.

Let’s start first by creating a Vehicle object.

A Vehicle object along with enums that defines it

Now let’s say you have a list of vehicles as defined below.

Creating a list of vehicles.

Let’s create a Filter class:

VehicleFilter class.

The way you would filter the a list of Vehicles is demostrated in the snippet below:

Filtering a list of vehicles.

This is good enough only if you know that a Vehicle has one property size. However, it’s bad enough to cater for changes in the Vehicle specification, i.e. it won’t work when we now want to filter the list of vehicles by colour or by vehicle type. Instead, we would have to add another function to our VehicleFilter which is poor practice as this does not follow the Open-Closed Principle (OCP).

How do we overcome this downside? Well, one of the solutions I would implement is to filter by specifications instead of explicitly stating the filtering criteria.

By doing this you allow your VehicleFilter to be flexible enough to cater for various filtering criteria.

Let’s define a vehicle specification.

VehicleSpecification.

Thus, we can specify our filtering criterion as follows:

SizeSpecification.
ColorSpecification.

Let’s create a Filter protocol.

Abstract Filter.
BestFilter which implements the Filter protocol.

Let’s see how the above changes will help us to abide by the Open-Closed Principle.

Filtering by color and size.

As you can see from the above code snippet, we can now filter for both colour and size without having to create two filters. This makes our filter class abide by the SRP (Single Responsibility Principle) and the OCP (Open-Closed Principle).

There’s a lot more you can do with the Specification pattern. For example, you can create a concrete specification that handles the case when you want to filter your list by both size and colour simultaneously. This is called the And Specification. However, there is a drawback with AND; it does not strictly follow the Single Responsibility Principle.

I hope you learned a lot about the Specification pattern.

I would also like to thank Kennedy Sigauke for his contribution to the making of this blog.

--

--