An introduction to Open Closed principle (OCP)

This is the fourth article on SOLID principles which I started a few weeks ago. I hope this is useful for you and that it gives you a simple understanding of what the Open/Closed principle is all about.

What is the Open Closed principle?

Bertrand Meyer coined the term Open/Closed Principle which appeared in his book titled Object Oriented Software Construction in 1988. The principle reads “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification“.

The Open Closed principle in my own words is about writing code in a way that you can extend its functionality later without having to change the existing classes – open for extension, but closed for modification. Requirements and rules around our code change all the time, the idea is to avoid changing code that has been released and instead figure out ways to extend it without modifying it directly.

An example of Closed Open principle violation

It is very easy to forget about this principle and end up changing the code every time a requirement or a rule changes. After all, trying to extend our code without modifying existing code is not always possible, but we should always try to limit that as much as possible.

The problem with changing existing code is that you’ll be increasing the complexity of it and the time it takes for new code to be released. As you make changes to existing code, you then have to test it to make sure it works. And then you also have to setup regression tests to make sure the new changes are not breaking existing (and expected) functionality. This isn’t always easy if your code base is quite large and it is also yet another way to introduce new bugs to your code base.

Consider the following code, it helps you determine a discount amount based on membership type:

class Membership
    {
        private int _membershipType;

        public int MembershipType
        {
            get { return _membershipType; }
            set { _membershipType = value; }
        }

        public double GetDiscount(double monthlyCost)
        {
            if (_membershipType == 1)
            {
                return monthlyCost - 100;
            }
            else
            {
                return monthlyCost - 50;
            }
        }
    }

The code above might seem to be OK and harmless. However, if we wanted to offer discounts to other type of memberships, we’ll have to modify the existing code to accomplish it. For example, if we wanted to offer specific discounts to other membership types, we’ll have to do so by adding more IF statements to the GetDiscount method in the example above. By modifying the existing code we’ll be breaking the Open/Closed principle.

How to satisfy the Open Closed principle

Instead of writing the code above, we could write code that allows a class to be extended without modifying it. The following code allows you to extend the Membership class without having to modify it. With the approach below, we could add specific discounts to other membership types without modifying the existing code:

class Membership
    {
        public virtual double GetDiscount(double monthlyCost)
        {
            return monthlyCost;
        }
    }

    class BronzeMembership : Membership
    {
        public override double GetDiscount(double monthlyCost)
        {
            return base.GetDiscount(monthlyCost) - 25;
        }
    }

    class SilverMembership : Membership
    {
        public override double GetDiscount(double monthlyCost)
        {
            return base.GetDiscount(monthlyCost) - 50;
        }
    }

    class GoldMembership : Membership
    {
        public override double GetDiscount(double monthlyCost)
        {
            return base.GetDiscount(monthlyCost) - 100;
        }
    }

In summary, keeping an eye on the Open Closed principle can help you write code that is extensible and cleaner. And following this principle would also help you design your classes following another of the SOLID principles, the Single Responsibility principle which I will be writing about next.

Happy coding!