Open Close Principle with example


It states that Class should be open for extension not for modification. Usually, many changes are involved when a new functionality is added to an application. Those changes in the existing code should be minimized, since it's assumed that the existing code is already unit tested and changes in already written code might affect the existing functionality. This is valuable for Production environment where the source codes has already been reviewed and tested. Adding the New functionality may causes the problem on existing code.

Intent

Class should be open for extension not for modification.

Example

Below example violates the rules of SRP & OCP. Suppose we are going to design a class for Shopping cart, Generally we need 3 basic functionalities for that
  1. GetProducts()
  2. ProcessOrder()
  3. ShipOrder()

On below example all the functionalities are in one class and it's shipping to US with dollar . Suppose later our system needs to support shipping to India with INR. Then it's quite difficult to modify the cose as it's already Unit tested and in Production. So here it's violating the rule of OCP.

class Customer
{
        public List<Product> GetProducts() 
        { 
            Console.WriteLine("Fetching products from db..."); 
            return new List<Product>();
        }
        public
void ProcessOrder()
        {
             Console.WriteLine("Process order in USD..");
        } 
        public void ShipOrder() 
        { 
            Console.WriteLine("Shipping to NY via flight..."); 
        } 
}


If the classes would have designed by follwing the Open Close Principle It may easy for developers to extend the class without modification. Let's see below how we can Implement OCP.

using System;
using System.Linq;
using System.Text;
 
namespace SOLIDPriciples
{
    class
Program
    {
        static void Main(string[] args)
        {
            Customer customer = new IndianCustomer();
            customer.ShipOrder();
            Console.ReadKey();
        }
    }
    class
Customer
    {
        public virtual void ShipOrder()
        {
            CustomerShipper customerShipper = new CustomerShipper();
            customerShipper.ShipOrder();
        }
    }
 
    class IndianCustomer :
Customer
    {
        public override void ShipOrder()
        {
            CustomerShipper customerShipper = new IndianCustomerShipper();
            customerShipper.ShipOrder();
           
//base.ShipOrder();
        }
    } 
 
    class
CustomerOrder
    {
        public virtual void ProcessOrder()
        {
            Console.WriteLine("Process order in USD..");
        }
    }
 
    class IndianCustomerOrder :
CustomerOrder
    {
        public override void ProcessOrder()
        {
            Console.WriteLine("Process order in INR..");
           
//base.ProcessOrder();
        }
    } 
    class
CustomerShipper
    {
        public virtual void ShipOrder()
        {
            DataAcess dataAcess = new DataAcess();
            dataAcess.GetProducts();
            CustomerOrder customerOrder = new CustomerOrder();
            customerOrder.ProcessOrder();
            Console.WriteLine("Shipping to NY via train...");
        }
    }

    class IndianCustomerShipper :
CustomerShipper
    {
        public override void ShipOrder()
        {
           
//base.ShipOrder();
            DataAcess dataAcess = new DataAcess();
            dataAcess.GetProducts();
            CustomerOrder customerOrder = new IndianCustomerOrder();
            customerOrder.ProcessOrder();
            Console.WriteLine("Shipping to Delhi via Flight...");
        }
    } 
    class
DataAcess
    {
        public List<Product> GetProducts()
        {
            Console.WriteLine("Fetching products from db...");
            return new List<Product>();
        }
    } 
    class
Product
    {
       Public int ProductID{get;set;}
       Public string ProductName {get;set;}
    }
}


So In Main method if we want our system should support shipping to both USA and India Then we can create instance of both Customer and IndianCustomer class.

Download the source code for more details.

Happy coding !