У меня есть сценарий, который основан на принципе Open Closed. У меня есть Cart
класс, который имеет метод CalculateTotal()
. Этот метод принимает MODE
и QTY
в качестве параметров.
На основе MODE
рассчитывается сумма.
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");
}
}
Если мне нужно добавить новое правило, скажем FestivalRule
, тогда я могу реализовать интерфейс, создать новое правило и добавить это правило в конструкторе Calculator()
.
Тем не менее я чувствую, что я изменяю класс Calculator
.
Есть ли способ, которым мне не нужно добавлять / изменять класс Calculator
, и все же применяется новое правило?