责任链模式适用的场景:
根据这段时间工作中代码重构的经验,我总结出,设计模式中的责任链模式,特别适合重构很长的if-else结构或者很长的switch-case结构的代码。
使用责任链模式对上述情景的代码进行重构后,会带来一下几个好处。
1,首先,很长的if-else结构或很长switch-case结构不见了,取而代之的是直接把处理情景交给一个责任链即可,代码十分简洁。
2,之前每个分支的代码,在责任链模式中,会被分布放到不同的处理类中。虽然类的个数不算少,但每个类的指责十分单一,便于维护。
在代码开发过程中,如果发现自己正在写很长的if-else代码或很长的switch-case代码时,不妨应用一下责任链模式。
以费控的控制模式举例:
using System; using ChainOfResponsibility.Structural; namespace ChainOfResponsibility { class Program { static void Main(string[] args) { int type = new Random().Next(1, 4); BudgetCalculation bc1 = new YearCumulativeCalculation(); BudgetCalculation bc2 = new QuarterlyCumulativeCalculation(); BudgetCalculation bc3 = new QuarterlyNonCumulativeCalculation(); BudgetCalculation bc4 = new NoControlCalculation(); //此处可以无限扩展控制类型 bc1.SetNextSuccessor(bc2); bc2.SetNextSuccessor(bc3); bc3.SetNextSuccessor(bc4); decimal remaindBudget = 0; bool result = bc1.BudgetCalculationRequest(type, DateTime.Now, "1.1.1", 400, ref remaindBudget); } } }
using System; using System.Collections.Generic; using System.Text; namespace ChainOfResponsibility.Structural { public enum TypeOfControl { /// <summary> /// 年度累计 /// </summary> YearCumulative = 1, /// <summary> /// 年度非累计 /// </summary> YearNonCumulative = 2, /// <summary> /// 季度累计 /// </summary> QuarterlyCumulative = 3, /// <summary> /// 季度非累计 /// </summary> QuarterlyNonCumulative = 4, /// <summary> /// 月度累计 /// </summary> MonthCumulative = 5, /// <summary> /// 月度非累计 /// </summary> MonthNonCumulative = 6, /// <summary> /// 不控 /// </summary> NoControl = 99, } }
using System; using System.Collections.Generic; using System.Text; namespace ChainOfResponsibility.Structural { /// <summary> /// 预算占用情况基类 /// </summary> public abstract class BudgetCalculation { protected BudgetCalculation successor; public void SetNextSuccessor(BudgetCalculation successor) { this.successor = successor; } public abstract bool BudgetCalculationRequest(int type, DateTime budgetTime, string budgetItemCode, decimal applyAmount, ref decimal remaindBudget); } /// <summary> /// 季度累计强控 /// </summary> public class QuarterlyCumulativeCalculation : BudgetCalculation { public override bool BudgetCalculationRequest(int type, DateTime budgetTime, string budgetItemCode, decimal applyAmount, ref decimal remaindBudget) { remaindBudget = 0; if (type == (int)TypeOfControl.QuarterlyCumulative) { DateTime begin = new DateTime(2019, 1, 1); DateTime end = new DateTime(2019, 6, 30); remaindBudget = 10000; return remaindBudget > applyAmount; } else if (successor != null) { return successor.BudgetCalculationRequest(type, budgetTime, budgetItemCode, applyAmount, ref remaindBudget); } else { throw new NotImplementedException("未实现的方法"); } } } /// <summary> /// 季度非累计强控 /// </summary> public class QuarterlyNonCumulativeCalculation : BudgetCalculation { public override bool BudgetCalculationRequest(int type, DateTime budgetTime, string budgetItemCode, decimal applyAmount, ref decimal remaindBudget) { remaindBudget = 0; if (type == (int)TypeOfControl.QuarterlyNonCumulative) { DateTime begin = new DateTime(2019, 4, 1); DateTime end = new DateTime(2019, 6, 30); remaindBudget = 100; return remaindBudget > applyAmount; } else if (successor != null) { return successor.BudgetCalculationRequest(type, budgetTime, budgetItemCode, applyAmount, ref remaindBudget); } else { throw new NotImplementedException("未实现的方法"); } } } /// <summary> /// 年度累计强控 /// </summary> public class YearCumulativeCalculation : BudgetCalculation { public override bool BudgetCalculationRequest(int type, DateTime budgetTime, string budgetItemCode, decimal applyAmount, ref decimal remaindBudget) { remaindBudget = 0; if (type == (int)TypeOfControl.YearCumulative) { DateTime begin = new DateTime(2019, 4, 1); DateTime end = new DateTime(2019, 6, 30); remaindBudget = 100; return remaindBudget > applyAmount; } else if (successor != null) { return successor.BudgetCalculationRequest(type, budgetTime, budgetItemCode, applyAmount, ref remaindBudget); } else { throw new NotImplementedException("未实现的方法"); } } } /// <summary> /// 不控 /// </summary> public class NoControlCalculation : BudgetCalculation { public override bool BudgetCalculationRequest(int type, DateTime budgetTime, string budgetItemCode, decimal applyAmount, ref decimal remaindBudget) { remaindBudget = 0; if (type == (int)TypeOfControl.NoControl) { return true; } else if (successor != null) { return successor.BudgetCalculationRequest(type, budgetTime, budgetItemCode, applyAmount, ref remaindBudget); } else { throw new NotImplementedException("未实现的方法"); } } } }