• 设计模式(十四)—— 职责链模式


    模式简介


    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一个链,并沿着链传递该请求,直到有一个对象处理它为止。

    职责链模式是一种行为型模式,它包括命令对象以及一系列处理对象。每个处理对象决定它能够处理哪些命令对象,将不能处理的命令对象传递至职责链中的下一个处理对象。

    想象一下公司的OA系统,提交请假单时系统会根据你的请假天数将申请单"交给"不同的人去审批,例如请假1-2天,只需要Team Leader审批,3-5天需要Manager审批,大于5天需要Director审批,这就形成了一个职责链。假如你要请假1个月,系统首先把请求传递给Leader对象,Leader对象发现自己无法处理这个请求,将请求传递给Manager对象,Manager也无法处理,再传递给Director。

    结构说明


    角色说明

    • Handler

    定义一个处理请求的接口。

    • ConcreteHandler

    实际负责处理请求的类。如果符合条件,处理该请求,否则转发给后续的ConcreteHandler。

    结构代码

    声明抽象类Handler,定义一个处理请求的接口。

    public abstract class Handler
    {
        protected Handler _successor;
        public void SetSuccessor(Handler successor)
        {
            this._successor = successor;
        }
        public abstract void Handle(int request);
    }
    

    具体实现类,负责处理请求。ConcreteHanlder1处理reqeust小于等于10的请求,其他由ConcreteHandler2进行处理。

    class ConcreteHandler1 : Handler
    {
        public override void Handle(int request)
        {
            if (request <= 10)
            {
                Console.WriteLine($"{this.GetType().Name} handled request {request}");
            }
            else if (_successor != null)
            {
                _successor.Handle(request);
            }
        }
    }
    
    class ConcreteHandler2 : Handler
    {
        public override void Handle(int request)
        {
            if (request > 10)
            {
                Console.WriteLine($"{this.GetType().Name} handled request {request}");
            }
            else if (_successor != null)
            {
                _successor.Handle(request);
            }
        }
    }
    

    客户端调用,设置职责链h1 -> h2,依次对requests数组中的元素进行处理。

    class Program
    {
        static void Main(string[] args)
        {
            ConcreteHandler1 h1 = new ConcreteHandler1();
            ConcreteHandler2 h2 = new ConcreteHandler2();
            h1.SetSuccessor(h2);
            int[] requests = { 1, 4, 5, 11, 24 };
            foreach (var request in requests)
            {
                h1.Handle(request);
            }
            Console.ReadLine();
        }
    }
    

    输出结果:

    工作原理

    当用户提交一个请求,请求将沿着职责链依次传递知道有一个ConcreteHandler对象负责处理它。

    示例分析


    回到本篇开头请假申请的示例,本节我们将通过职责链模式来实现它,首先创建请求类LeaveReqeust,包含申请人以及申请天数,

    class LeaveRequest
    {
        public string Applicant { get; set; }
        public int Days { get; set; }
    }
    

    声明抽象类Approver,定义一个处理请求的抽象方法Approve。

    abstract class Approver
    {
        protected Approver _successor;
        public void SetSuccessor(Approver successor)
        {
            _successor = successor;
        }
    
        public abstract void Approve(LeaveRequest request);
    }
    

    声明Leader、Manager、Director三个实际处理请求的类。

    class Leader : Approver
    {
        public override void Approve(LeaveRequest request)
        {
            if (request.Days <= 2)
            {
                Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
            }
            else if (_successor != null)
            {
                _successor.Approve(request);
            }
        }
    }
    
    class Manager : Approver
    {
        public override void Approve(LeaveRequest request)
        {
            if (request.Days <= 5)
            {
                Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
            }
            else if (_successor != null)
            {
                _successor.Approve(request);
            }
        }
    }
    
    class Director : Approver
    {
        public override void Approve(LeaveRequest request)
        {
            Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
        }
    }
    

    客户端调用,创建职责链leader->manager->director,接着创建3个请求传递给职责链,依次处理。

    class Program
    {
        static void Main(string[] args)
        {
            Leader leader = new Leader();
            Manager manager = new Manager();
            Director director = new Director();
            leader.SetSuccessor(manager);
            manager.SetSuccessor(director);
    
            LeaveRequest jack = new LeaveRequest
            {
                Applicant = "Jack",
                Days = 2
            };
    
            LeaveRequest tom = new LeaveRequest
            {
                Applicant = "Tom",
                Days = 30
            };
    
            LeaveRequest mike = new LeaveRequest
            {
                Applicant = "Mike",
                Days = 4
            };
    
            leader.Approve(jack);
            leader.Approve(tom);
            leader.Approve(mike);
            Console.ReadLine();
        }
    }
    

    输出结果:

    适用场景


    • 由多个对象处理一个请求,在运行时确定具体使哪个对象进行处理

    • 职责链可以动态指定

  • 相关阅读:
    Mysql 创建用户并授权方法
    anyproxy 拦截响应
    Pycharm中加载和使用虚拟环境
    anyproxy 拦截发送请求
    微信小程序测试
    Django admin 后台管理
    Django简介
    Mysql root 密码忘记解决办法
    APP专项测试_启动性能分析
    Windows环境搭建Python虚拟环境
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9213010.html
Copyright © 2020-2023  润新知