Press "Enter" to skip to content

Open Closed Principle in C# – OCP

Hi, everyone! Todays topic is Open closed principle! we’ll explain 2nd letter of SOLID principle. We gonna write some code in c#.

Now, let’s take a look at the technological products that we use today. All the products have changed so far as to reach the last version we are currently using? hmmm, this is not only the technological products, but all the existing systems apply to this. Everything changed!

As you know, the only thing that doesn’t change is change! 

Well; If the products we are producing will change over time, then we should make this change the lowest cost, right? To achieve this, we obtain a product by combining many parts.

For example, a car actually consists of thousands of parts. Wheels, crankshaft, engine, battery, storage and so on can be applied to an existing car, for example, when a new tire technology is developed. All you have to do is change your car’s tires. Imagine that you have to change the car completely to change a tire! Sounds bad right?

The objects you use in your project are just like parts of a machine. Therefore, the functions and numbers of these objects may vary. So you need to design such a structure that the development is ON but the source code must be switched OFF. That’s exactly the key phrase of the open-closed principle. But I still consider writing the sentence of Bertrand Meyer, the architect of this notion, as a debt: Software assets (classes, modules, functions, etc.) should be open to development, and CLOSED to code change.

Open Closed Principle with C# example Code

Lets write some code! I’ve just created a scenario! We have a e-commerce web application and we would like to discount according to customer’s membership type! We have premium & standard membership.

    public enum MemberShipType
    {
        Standard,
        Premium
    }

and, our customer class:

    public class Customer
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string LastName { get; set; }
        public MemberShipType MemberShip { get; set; }
    }

and now, Order class & calculating discount function:

    public class Order
    {
        public decimal CalculatePrice(decimal price, Customer customer)
        {
            decimal result = 0;
            switch (customer.MemberShip)
            {
                case MemberShipType.Standard:
                    result = price;
                    break;
                case MemberShipType.Premium:
                    result = price * (1 - 0.1M);
                    break;
                default:
                    break;
            }
            return result;
        }
    }

Everything looks good! But there is a problem. In the future, if one more member ship type added to system, what will we do? Hmmm…

Your project is not open to objective development. Because if you want to make a development as mentioned, you need to change your source code seriously. So after adding the value “Gold. In the MemberShipType, you need to add a new case blablabla..

This is not something we want. In Open-Closed Principle says that ‘Software assets
should be open to development, and CLOSED to code change. ‘

If we want this scenario to be available with the OCP, I need to design the Order class so that I never need to change it again. I also need to get rid of the enum type so that the structure can be improved!

Now my friends, here is our hero! Abstract class!

  public abstract class MemberShipType
    {
        public abstract decimal CalculatePrice(decimal price);
    }

public class StandardMemberShip : MemberShipType
    {
        public override decimal CalculatePrice(decimal price)
        {
            return price;
        }
    }

    public class PremiumMemberShip : MemberShipType
    {
        public override decimal CalculatePrice(decimal price)
        {
            return price * (1 - 0.1M);
        }
    }

   public class Order
    {
        public decimal CalculatePrice(decimal price, Customer customer)
        {
            return customer.MemberShip.CalculatePrice(price);
        }
    }

If you want to add Gold membership, all you have to do is to build a new class that derives from the MemberShipType class! Now it is available with OCP!

I am asking the main questions:

  • If new membership type added to project, will we change the source Order code? (NO!)
  • Can I improve the project by adding as many membership types as I want? (YES!)

This is Open Closed Principle my friends! We did wrote some code in C#! i hope you got learned. Share your ideas with me.

Thanks for reading, see you on next SOLID principle!

Eat, sleep & SOLID!

Comments are closed.