I have a scenario which is based on the Open Closed principle. I have a Cart
class, which has a method CalculateTotal()
. This method takes MODE
and QTY
as parameters.
Based on the MODE
, the amount is calculated.
public class Cart
{
ICalculator calculator;
public Cart()
{
calculator = new Calculator();
}
public decimal CalculateTotal(string MODE,decimal QTY)
{
return calculator.CalculateTotal(MODE, QTY);
}
}
public interface ICalculator
{
decimal CalculateTotal(string MODE, decimal QTY);
}
public class Calculator : ICalculator
{
private readonly List<IRule> rules;
public Calculator()
{
rules = new List<IRule>();
rules.Add(new OrdinaryRule());
rules.Add(new SpecialRule());
rules.Add(new OfferRule());
}
public decimal CalculateTotal(string MODE, decimal QTY)
{
return rules.First(x => x.IsMatch(MODE)).CalculateTotal(QTY);
}
}
public interface IRule
{
bool IsMatch(string MODE);
decimal CalculateTotal(decimal QTY);
}
public class OrdinaryRule : IRule
{
public decimal CalculateTotal(decimal QTY)
{
return QTY * 2m;
}
public bool IsMatch(string MODE)
{
return MODE.StartsWith("ORD");
}
}
If I need to add a new rule say FestivalRule
, then I can implement the interface and create a new rule and add that rule in the Calculator()
constructor.
Still I feel that I'm modifying the Calculator
class.
Is there any way that I don't have to add/ modify the Calculator
class and still the new rule applies?