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
- GetProducts()
- ProcessOrder()
- 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 !

amit prajapatiPosted Sep 21, 2017, 8:52 AM
Too much complicated it can be simple.
Rajesh Kumar MauryaPosted Jul 21, 2017, 9:40 AM
Great and simple article...
sitanshu PandaPosted Aug 22, 2016, 2:07 AM
Lot of issues in the given example.
Anil KumarPosted May 27, 2016, 1:19 AM
Hi , I read your post and trying to understand , but still i have one question in calling method Main i need to change every time for Customer and IndianCustomer , there is any way we did not change the calling methods, I have customer then how can we decide its IndiaCustomer or for Customer , and in your example you have pass the IndiaCustomer in Main method