• 19.Chain of Responsibility职责链(行为型模式)


    一:动机(Motivation)

    在这里插入图片描述

    <1>在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。
    <2>如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。

    二:意图(Intent)

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

    三:结构(Structure)

    在这里插入图片描述

    在这里插入图片描述

    四:结构详解

    在这里插入图片描述

    五:生活中的例子

    员工向主管上级提出申请

    申请有两种:请假和加薪
    职责链是:总监>经理>总经理
    总监能处理:请假,且在2小时以内
    经理能处理:请假,且在5小时以内
    总经理能处理:
    请假:小时不限,都通过
    加薪:
    1000元以内批准
    1000元以上要考察再说

    在这里插入图片描述

    六:实现

    namespace Test
    {
        public enum 申请类型
        {
            请假,
            加薪
        }
    
        /// 
        /// 实现申请
        /// 
        public class 申请
        {
            public 申请类型 类型;
            public string 内容;
            public int 数量;
            public override string ToString()
            {
                return string.Format("内容:{0},类型:{1},数量:{2}", this.内容, this.类型, this.数量);
            }
        }
    
        /// 
        /// 实现管理者
        /// 
        public abstract class 管理者
        {
            protected string name;
            public 管理者(string 姓名)
            {
                this.name = 姓名;
            }
    
            protected 管理者 superior;
            public 管理者 上级主管
            {
                get { return this.superior; }
                set { this.superior = value; }
            }
    
            public abstract void 处理员工申请(申请 request);
        }
    
        /// 
        /// 实现总监
        /// 
        public class 总监 : 管理者
        {
            public 总监(string 姓名) : base(姓名) { }
    
            public override void 处理员工申请(申请 request)
            {
                if (request.类型 == 申请类型.请假 && request.数量 <= 2)
                {
                    Console.WriteLine("总监:{0},通过 {1} 申请,数量:{2}", base.name, request.内容, request.数量);
                }
                else
                {
                    if (base.superior != null)
                    {
                        Console.WriteLine("总监:{0},无权处理 {1} 申请,数量:{2},转交给上级", base.name, request.内容, request.数量);
                        base.superior.处理员工申请(request);
                    }
                }
            }
        }
    
        /// 
        /// 实现经理
        /// 
        public class 经理 : 管理者
        {
            public 经理(string 姓名) : base(姓名) { }
    
            public override void 处理员工申请(申请 request)
            {
                if (request.类型 == 申请类型.请假 && request.数量 <= 5)
                {
                    Console.WriteLine("经理:{0},通过 {1} 申请,数量:{2}", base.name, request.内容, request.数量);
                }
                else
                {
                    if (base.superior != null)
                    {
                        Console.WriteLine("经理:{0},无权处理 {1} 申请,数量:{2},转交给上级", base.name, request.内容, request.数量);
                        base.superior.处理员工申请(request);
                    }
                }
            }
        }
    
        /// 
        /// 实现总经理
        /// 
        public class 总经理 : 管理者
        {
            public 总经理(string 姓名) : base(姓名) { }
    
            public override void 处理员工申请(申请 request)
            {
                if (request.类型 == 申请类型.请假)
                {
                    Console.WriteLine("总经理:{0},通过 {1} 申请,数量:{2}", base.name, request.内容, request.数量);
                    return;
                }
                else
                {
                    if (request.类型 == 申请类型.加薪 && request.数量 <= 1000)
                    {
                        Console.WriteLine("总经理:{0},无权处理 {1} 申请,数量:{2}", base.name, request.内容, request.数量);
                        return;
                    }
                    else
                    {
                        Console.WriteLine("总经理:{0},没有通过 {1} 申请,数量:{2},再考察一下工作表现再说吧", base.name, request.内容, request.数量);
                        return;
                    }
                }
            }
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                申请 request = new 申请();
                request.类型 = 申请类型.请假;
                request.数量 = 1;
                request.内容 = "小李要请假";
    
                管理者 张三 = new 总监("张三");
                管理者 李四 = new 经理("李四");
                管理者 王五 = new 总经理("王五");
                张三.上级主管 = 李四;
                李四.上级主管 = 王五;
    
                Console.WriteLine("\n第1次申请:{0}", request);
                张三.处理员工申请(request);
                request.数量 = 8;
                Console.WriteLine("\n第2次申请:{0}", request);
                张三.处理员工申请(request);
    
                request.类型 = 申请类型.加薪;
                request.内容 = "小李要涨工资";
                request.数量 = 800;
                Console.WriteLine("\n第3次申请:{0}", request);
                张三.处理员工申请(request);
    
                request.数量 = 1500;
                Console.WriteLine("\n第4次申请:{0}", request);
                张三.处理员工申请(request);
                Console.ReadLine();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155

    实现-结果

    在这里插入图片描述

    七:实现要点

    <1>链的顺序可灵活改变-改变”上级主管”即可;
    <2>发起请求者只需要将请求发送给”最近”的上级,即总监,不需要关心后续的链接关系。

    八:适用性

    <1>系统已经有一个由处理者对象组成的链。这个链可能由复合模式给出;
    <2>当有多于一个的处理者对象会处理一个请求,而且在事先并不知道到底由哪一个处理者对象处理一个请求。这个处理者对象是动态确定的;
    <3>当系统想发出一个请求给多个处理者对象中的某一个,但是不明显指定是哪一个处理者对象会处理此请求;
    <4>当处理一个请求的处理者对象集合需要动态地指定时。

    九:总结

    <1>Chain of Responsibility 模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只有一个”,只有这时候请求发送者与接受者的耦合才有可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应对变化。
    <2>应用了Chain of Responsibility 模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
    <3>如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。

  • 相关阅读:
    绕过UNION&SELECT过滤
    elementUI-表单-校验
    2023-09-22力扣每日一题
    基于py的网络路由实验
    数据结构:图(树也是图的一种),有向图和无向图,连通图和非连通图,有向图出度入度
    NLTK安装使用全过程--python
    SIT1050ISO 数字隔离接口芯片替代 ISO1050DUBR 电容隔离的CAN转发器
    题目0113-选座位
    最新版MySQL 8.0 的下载与安装(详细教程)
    1370:最小函数值(minval)——优先队列
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/126676382