- 责任链模式:字面意思,什么职位负什么责。也就流程责任模式。
- 定义:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。
先看一个背景:如果让你做个流程代码。就是做一个公司请假审批。因为请假时长不同,所以负责的职位也不同。10小时之内的项目经理就能审批了。若是30小时总监才有这个职责。所以第一个审批代码如下:
public class Program { public static void Main(int[] args) { { //请假条上下文 ApprovalContext approvalContext = new ApprovalContext("换",50,"生孩子",""); //1 审批流程 需求 if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批逻辑...."); } else if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("部门主管审批逻辑...."); } else if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批逻辑...."); } else if (30 < approvalContext.Num && approvalContext.Num < 40) { Console.WriteLine("CEO审批逻辑...."); } else { Console.WriteLine("董事会审批逻辑...."); } } } } ///假条 public class ApprovalContext { /// <summary> /// /// </summary> public string Name { get; set; } /// <summary> /// /// </summary> public int Num { get; set; } /// <summary> /// /// </summary> public string Reason { get; set; } /// <summary> /// /// </summary> public string Remark { get; set; } public ApprovalContext(string name,int num,string reason,string remark) { Name = name; Num = num; Reason = reason; Remark = remark; } }
第二步:毫无设计感,只是为了业务而业务。不满足高可用、可扩展。针对这个面向对象第一步优化
public class Program { public static void Main(int[] args) { { //请假条上下文 ApprovalContext approvalContext = new ApprovalContext("换",50,"生孩子",""); //1 审批流程 需求 if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批逻辑...."); } else if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("部门主管审批逻辑...."); } else if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批逻辑...."); } else if (30 < approvalContext.Num && approvalContext.Num < 40) { Console.WriteLine("CEO审批逻辑...."); } else { Console.WriteLine("董事会审批逻辑...."); } //2 面向对象优化(还是审批逻辑指定了,不满足扩展需求。比如说换人了,ceo不是小红了) { ProjectManager projectManager = new ProjectManager("小明"); projectManager.Approval(approvalContext); } } } } public class ProjectManager { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ProjectManager(string approverName) { ApproverName = approverName; } public void Approval(ApprovalContext approvalContext) { if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("审批通过或不通过逻辑"); } else { //指定下一审批流程 ExecutiveDirector executiveDirector = new ExecutiveDirector("Nice"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 主管 /// </summary> public class ExecutiveDirector { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ExecutiveDirector(string approverName) { ApproverName = approverName; } public void Approval(ApprovalContext approvalContext) { if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("审批通过或不通过逻辑"); } else { //指定下一审批流程 ChiefInspector executiveDirector = new ChiefInspector("小美"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 总监 /// </summary> public class ChiefInspector { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ChiefInspector(string approverName) { ApproverName = approverName; } public void Approval(ApprovalContext approvalContext) { if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("审批通过或不通过逻辑"); } else { //指定下一审批流程 CEO executiveDirector = new CEO("小红"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// CEO /// </summary> public class CEO { /// <summary> /// 审批人 /// </summary> private string ApproverName; public CEO(string approverName) { ApproverName = approverName; } public void Approval(ApprovalContext approvalContext) { if (30 < approvalContext.Num && approvalContext.Num <= 40) { Console.WriteLine("审批通过或不通过逻辑"); } else { //指定下一审批流程 Chairman executiveDirector = new Chairman("小赵"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 董事长 /// </summary> public class Chairman { /// <summary> /// 审批人 /// </summary> private string ApproverName; public Chairman(string approverName) { ApproverName = approverName; } public void Approval(ApprovalContext approvalContext) { Console.WriteLine("审批通过或不通过逻辑"); } }
第三步:因为有共同的方法、属性。面向对象和面向抽象在优化一下。
public class Program { public static void Main(int[] args) { { //请假条上下文 ApprovalContext approvalContext = new ApprovalContext("换",50,"生孩子",""); //1 审批流程 需求 if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批逻辑...."); } else if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("部门主管审批逻辑...."); } else if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批逻辑...."); } else if (30 < approvalContext.Num && approvalContext.Num < 40) { Console.WriteLine("CEO审批逻辑...."); } else { Console.WriteLine("董事会审批逻辑...."); } //2 面向对象优化(还是审批逻辑指定了,不满足扩展需求。比如说换人了,ceo不是小红了) { ProjectManager projectManager = new ProjectManager("小明"); projectManager.Approval(approvalContext); } //3 因为都有一样的属性和审批方法。面向对象和抽象在优化一下 { AbstraactApproval projectManager = new ProjectManager("小明"); projectManager.Approval(approvalContext); } } } } public abstract class AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public AbstraactApproval(string approverName) { ApproverName = approverName; } public abstract void Approval(ApprovalContext approvalContext); } ///项目经理 public class ProjectManager: AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ProjectManager(string approverName):base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批通过或不通过逻辑"); } else { //指定下一审批流程 ExecutiveDirector executiveDirector = new ExecutiveDirector("Nice"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 主管 /// </summary> public class ExecutiveDirector : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ExecutiveDirector(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("主管审批通过或不通过逻辑"); } else { //指定下一审批流程 ChiefInspector executiveDirector = new ChiefInspector("小美"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 总监 /// </summary> public class ChiefInspector : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ChiefInspector(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批通过或不通过逻辑"); } else { //指定下一审批流程 CEO executiveDirector = new CEO("小红"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// CEO /// </summary> public class CEO : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public CEO(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (30 < approvalContext.Num && approvalContext.Num <= 40) { Console.WriteLine("CEO审批通过或不通过逻辑"); } else { //指定下一审批流程 Chairman executiveDirector = new Chairman("小赵"); executiveDirector.Approval(approvalContext); } } } /// <summary> /// 董事长 /// </summary> public class Chairman : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public Chairman(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { Console.WriteLine("董事长审批通过或不通过逻辑"); } }
第四步:外抛大法,将可变配置(流程)交给调用端配置。
public class Program { public static void Main(int[] args) { { //请假条上下文 ApprovalContext approvalContext = new ApprovalContext("换",20,"生孩子",""); //1 审批流程 需求 if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批逻辑...."); } else if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("部门主管审批逻辑...."); } else if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批逻辑...."); } else if (30 < approvalContext.Num && approvalContext.Num < 40) { Console.WriteLine("CEO审批逻辑...."); } else { Console.WriteLine("董事会审批逻辑...."); } //2 面向对象优化(还是审批逻辑指定了,不满足扩展需求。比如说换人了,ceo不是小红了) { ProjectManager projectManager = new ProjectManager("小明"); projectManager.Approval(approvalContext); } //3 因为都有一样的属性和审批方法。面向对象和抽象在优化一下 { AbstraactApproval projectManager = new ProjectManager("小明"); projectManager.Approval(approvalContext); } //4解决2、3问题。就是结构模式的方法。逻辑向外抛出去。让外面决定。 { //刚刚因为指定了一下步骤,导致不好扩展。所以将共同的指定下一步抛出去,让前面应用决定 AbstraactApproval projectManager = new ProjectManager("小明");//这里都是里式替换原则 AbstraactApproval ExecutiveDirectorApproval = new ExecutiveDirector("随便");//这里都是里式替换原则 AbstraactApproval ChiefInspectorApproval = new ChiefInspector("随便");//这里都是里式替换原则 AbstraactApproval CEOApproval = new CEO("随便");//这里都是里式替换原则 AbstraactApproval ChairmanApproval = new Chairman("随便");//这里都是里式替换原则 projectManager.SetNextApproval(ExecutiveDirectorApproval); ExecutiveDirectorApproval.SetNextApproval(ChiefInspectorApproval); ChiefInspectorApproval.SetNextApproval(CEOApproval); CEOApproval.SetNextApproval(ChairmanApproval); projectManager.Approval(approvalContext); //具体审批流程交给上端去配置 } } } } public abstract class AbstraactApproval { public AbstraactApproval _abstraactApprovalNext = null; /// <summary> /// 指定下一个审批流程 /// </summary> public void SetNextApproval(AbstraactApproval abstraactApproval) { _abstraactApprovalNext = abstraactApproval; } /// <summary> /// 审批人 /// </summary> private string ApproverName; public AbstraactApproval(string approverName) { ApproverName = approverName; } /// <summary> /// 审批 /// </summary> /// <param name="approvalContext"></param> public abstract void Approval(ApprovalContext approvalContext); } /// <summary> /// 项目经理 /// </summary> public class ProjectManager: AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ProjectManager(string approverName):base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (0 < approvalContext.Num && approvalContext.Num <= 10) { Console.WriteLine("项目经理审批通过或不通过逻辑"); } if (_abstraactApprovalNext != null) { _abstraactApprovalNext.Approval(approvalContext); } } } /// <summary> /// 主管 /// </summary> public class ExecutiveDirector : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ExecutiveDirector(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (10 < approvalContext.Num && approvalContext.Num <= 20) { Console.WriteLine("主管审批通过或不通过逻辑"); } if (_abstraactApprovalNext != null) { _abstraactApprovalNext.Approval(approvalContext); } } } /// <summary> /// 总监 /// </summary> public class ChiefInspector : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public ChiefInspector(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (20 < approvalContext.Num && approvalContext.Num <= 30) { Console.WriteLine("总监审批通过或不通过逻辑"); } if (_abstraactApprovalNext != null) { _abstraactApprovalNext.Approval(approvalContext); } } } /// <summary> /// CEO /// </summary> public class CEO : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public CEO(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { if (30 < approvalContext.Num && approvalContext.Num <= 40) { Console.WriteLine("CEO审批通过或不通过逻辑"); } if (_abstraactApprovalNext != null) { _abstraactApprovalNext.Approval(approvalContext); } } } /// <summary> /// 董事长 /// </summary> public class Chairman : AbstraactApproval { /// <summary> /// 审批人 /// </summary> private string ApproverName; public Chairman(string approverName) : base(approverName) { ApproverName = approverName; } public override void Approval(ApprovalContext approvalContext) { Console.WriteLine("董事长审批通过或不通过逻辑"); } }
总结:使用责任链模式的条件就是字面意思,很多时候,想歪了。就是解决流程问题。流程出现很多判断,就可以用这个模式去面向对象,面向抽象去设计、扩展。
重点:行为模式是关注类和行为。同过业务去分析行为然后再去面向对象(封装、继承、多态),一步一步去设计。