行为型设计模式之-责任链模式

  • 责任链模式:字面意思,什么职位负什么责。也就流程责任模式。
  • 定义:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

先看一个背景:如果让你做个流程代码。就是做一个公司请假审批。因为请假时长不同,所以负责的职位也不同。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("董事长审批通过或不通过逻辑");
        }
    }

总结:使用责任链模式的条件就是字面意思,很多时候,想歪了。就是解决流程问题。流程出现很多判断,就可以用这个模式去面向对象,面向抽象去设计、扩展。

重点:行为模式是关注类和行为。同过业务去分析行为然后再去面向对象(封装、继承、多态),一步一步去设计。

本文来自博客园,作者:小换哥,转载请注明原文链接:https://www.cnblogs.com/haunge/p/15039129.html

原文地址:https://www.cnblogs.com/haunge/p/15039129.html