C# 自动插入呼叫
我有一个基于开闭原理的场景。我有一个C# 自动插入呼叫,c#,solid-principles,open-closed-principle,C#,Solid Principles,Open Closed Principle,我有一个基于开闭原理的场景。我有一个Cart类,它有一个方法CalculateTotal()。此方法将模式和数量作为参数 根据模式,计算金额 public class Cart { ICalculator calculator; public Cart() { calculator = new Calculator(); } public decimal CalculateTotal(string MODE,decimal QTY)
Cart
类,它有一个方法CalculateTotal()
。此方法将模式
和数量
作为参数
根据模式
,计算金额
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");
}
}
公共类购物车
{
计算器;
公共购物车()
{
计算器=新计算器();
}
公共十进制计算器总计(字符串模式,十进制数量)
{
返回计算器.CalculateTotal(模式、数量);
}
}
公共接口计算器
{
十进制计算器总计(字符串模式,十进制数量);
}
公共类计算器:ICalculator
{
私有只读列表规则;
公共计算器()
{
规则=新列表();
添加(新的OrdinaryRule());
添加(新的SpecialRule());
添加(新要约());
}
公共十进制计算器总计(字符串模式,十进制数量)
{
返回规则.First(x=>x.IsMatch(MODE)).CalculateTotal(数量);
}
}
公共接口病毒
{
布尔IsMatch(字符串模式);
十进制计算器总计(十进制数量);
}
公共类普通规则:IRule
{
公共十进制计算器总计(十进制数量)
{
退货数量*2m;
}
公共布尔IsMatch(字符串模式)
{
返回模式。使用“ORD”启动;
}
}
如果我需要添加一个新规则,比如说FestivalRule
,那么我可以实现接口并创建一个新规则,然后将该规则添加到Calculator()
构造函数中
我仍然觉得我在修改计算器类
有没有什么方法可以让我不必添加/修改计算器
类,而新规则仍然适用 当前的设计仍然将类与实现问题紧密结合在一起
使用策略模式和显式依赖原则注入依赖项
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);
}
}
公共类购物车{
专用只读计算器;
公共购物车(ICalculator计算器){
this.calculator=计算器;
}
公共十进制计算器总计(字符串模式,十进制数量){
返回计算器.CalculateTotal(模式、数量);
}
}
公共类计算器:ICalculator{
私有只读列表规则;
公共计算器(IEnumerable规则){
this.rules=新列表(规则);
}
公共十进制计算器总计(字符串模式,十进制数量){
返回规则.First(x=>x.IsMatch(MODE)).CalculateTotal(数量);
}
}
因此,现在无论是使用纯DI还是容器,这些类都与实现问题解耦,可以允许在不修改源代码(OCP)的情况下扩展它们的行为
列表规则=新建列表();
添加(新的OrdinaryRule());
添加(新的SpecialRule());
添加(新要约());
添加(新的节日规则())//你需要的是一个。IOC容器使用策略模式和显式依赖原则注入规则集合。当前的设计仍然将计算器与实现问题紧密结合。
List<IRule> rules = new List<IRule>();
rules.Add(new OrdinaryRule());
rules.Add(new SpecialRule());
rules.Add(new OfferRule());
rules.Add(new FestivalRule()); //<<<
var calculator = new Calculator(rules);
var cart = new Cart(calculator);
//...