自动拨打电话

时间:2018-07-01 11:53:06

标签: c# solid-principles open-closed-principle

我有一个基于开放式封闭原则的方案。我有一个Cart类,它有一个方法CalculateTotal()。此方法将MODEQTY作为参数。

根据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类并且仍然适用新规则的方法?

1 个答案:

答案 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容器将负责繁重的工作以及依赖项的自动注入。只要已对其进行了相应的配置。