我有一个基于开放式封闭原则的方案。我有一个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
类并且仍然适用新规则的方法?
答案 0 :(得分:2)
当前的设计仍将您的类与实现方面紧密联系在一起。
使用策略模式和显式依赖原理注入依赖关系。
newScores[newScores.length -1] = oldScores[0];
for (i = 0; i < oldScores.length - 1; i++) {
newScores[i] = oldScores[i +1];
}
for (i = 0; i < newScores.length; ++i) {
System.out.print(newScores[i] + " ");
}
因此,现在无论是使用纯DI还是使用容器,这些类都与实现问题脱钩,可以在不修改源代码(OCP)的情况下扩展其行为。
public class Cart {
private readonly ICalculator calculator;
public Cart(ICalculator calculator) {
this.calculator = calculator;
}
public decimal CalculateTotal(string MODE, decimal QTY) {
return calculator.CalculateTotal(MODE, QTY);
}
}
public class Calculator : ICalculator {
private readonly List<IRule> rules;
public Calculator(IEnumerable<IRule> rules) {
this.rules = new List<IRule>(rules);
}
public decimal CalculateTotal(string MODE, decimal QTY) {
return rules.First(x => x.IsMatch(MODE)).CalculateTotal(QTY);
}
}
在解析对象图时,DI容器将负责繁重的工作以及依赖项的自动注入。只要已对其进行了相应的配置。