In My previous post I have explained the
implementation of Single Responsibility Principle (SRP) using c#. Here I would
like to provide Open Close Principle(OCP) using c#. As per this design
principle application should be able to extend the code & should not be
allow for Modification.
Open Close Principle implementation
There is no much difference in invoking the
implementation. Only needs to add Mileage property in initialization.
“Software application source
codes should be open for extension but should be closed for modification.”
Please find the below Code:
/// <summary>
/// Car Object
/// </summary>
public class
Car
{
public
string Name { get;
set; }
}
/// <summary>
///
Calculating Mileage for each car
/// </summary>
public class
MileageCalculator
{
IEnumerable<Car> _cars;
public
MileageCalculator(IEnumerable<Car> cars)
{
this._cars
= cars;
}
public void CalculateMileage()
{
foreach
(var car in
_cars)
{
if
(car.Name == "Maruthi")
Console.WriteLine("Mileage of the car {0} is {1}",
car.Name, "10M");
else
if (car.Name == "Ford")
Console.WriteLine("Mileage of the car {0} is {1}",
car.Name, "20M");
}
}
}
The
above code snippet is following SRP principle. But it is completely concrete.
Ie if we needs to change the mileage of a car we needs to change the
implementation. This is against the OCP rule of Design. You can see the call of
the implementation.
Invoke the Implementation
List<Car> lstCar = new
List<Car>();
lstCar.Add(new
Car { Name = "Maruthi"
});
lstCar.Add(new
Car { Name = "Ford"
});
MileageCalculator
mlc = new MileageCalculator(lstCar);
mlc.CalculateMileage();
/// <summary>
/// Calculating Mileage for each car
/// </summary>
public class
MileageCalculator
{
IEnumerable<ICar> _cars;
public
MileageCalculator(IEnumerable<ICar> cars)
{
this._cars
= cars;
}
public void CalculateMileage()
{
CarController
controller = new CarController(_cars);
foreach
(var car in
_cars)
{
Console.WriteLine("Mileage of the car {0} is {1}",
car.Name, controller.GetCarMileage(car.Name));
}
}
}
/// <summary>
/// Car
controller Class
/// </summary>
public class
CarController
{
public IEnumerable<ICar>
cars;
public
CarController(IEnumerable<ICar> icars)
{
cars = icars;
}
public string GetCarMileage(string
name)
{
return
cars.First(car => car.Name.Equals(name)).GetMileage();
}
}
/// <summary>
/// Interface
for Car
/// </summary>
public interface
ICar
{
string
Name { get; set;
}
string
Mileage { get; set;
}
string
GetMileage();
}
/// <summary>
/// Creating
different Class(Ford)
/// </summary>
public class
Ford : ICar
{
public string Name
{
get;
set;
}
public string Mileage
{
get;
set;
}
public string GetMileage()
{
return
Mileage;
}
}
/// <summary>
/// Creating different Class(Maruthi)
/// </summary>
public class
Maruthi : ICar
{
public string Name
{
get;
set;
}
public string Mileage
{
get;
set;
}
public string GetMileage()
{
return
Mileage;
}
}
Here I have split the Car objects to more
generalized way, class “Car” moved to ‘Ford’ & ‘Maruthi’ with the help of
“ICar” Interface. I have added new
Property & one method for Getting Mileage.
Invoke the Implementation
List<ICar> lstCar = new
List<ICar>();
lstCar.Add(new
Maruthi { Name = "Maruthi"
, Mileage="20Km" });
lstCar.Add(new
Ford { Name = "Ford"
,Mileage = "15km"});
MileageCalculator
mlc = new MileageCalculator(lstCar);
mlc.CalculateMileage();
You may think that how it allow extension
without modifying the source code. Assume that you needs to add one more car
object like “Fiat” What are the thinks needs to do?.
Add One More Class in to the same Namespace
Like the below
/// <summary>
/// Creating
different Class(Fiat)
/// </summary>
public class
Fiat : ICar
{
public string Name
{
get;
set;
}
public string Mileage
{
get;
set;
}
public string GetMileage()
{
return
Mileage;
}
}
Add One more Object in the invoke call Like
below . Instead of this one we can make Car object as configurable
in Config or XML File.
List<ICar> lstCar = new
List<ICar>();
lstCar.Add(new
Maruthi { Name = "Maruthi"
, Mileage="20Km" });
lstCar.Add(new
Ford { Name = "Ford"
,Mileage = "15km"});
lstCar.Add(new Fiat { Name = "Fiat",
Mileage = "18 KM" });
MileageCalculator
mlc = new MileageCalculator(lstCar);
mlc.CalculateMileage();
No comments:
Post a Comment