设计模式-行为型-职责链模式

职责链模式(Chain of Responsibility):

  在现实生活中,常常会出现这样的事例:一个请求需要多个对象处理,但每个对象的处理条件或权限不同。如公司员工报销差旅费,可审批的领导有部分负责人、副总经理、总经理等,但每个领导能审批的金额是不同的,不同的金额需要找相应的领导审批,也就是说要报销必须先搞清楚需要谁来审批。职责链模式就是为了解决这样的问题产生的。

  职责链模式,又叫责任链模式。是为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一个对象记住其下一个对象的引用而连成一条链。当发生请求时,可将请求沿着这条链传递,直到有对象处理它为止。

职责链模式的角色:

  

  1)抽象处理者(Handler):声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法

  2)具体处理者(ConcreteHandler):包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。

  3)请求信息(Request):定义请求的信息。

  4)客户端(Client):可根据程序逻辑一次性或者动态地生成链。值得注意的是,请求可发送给链上的任意一个处理者,而非必须是第一个处理者。

责任链的实现:(以请假为例)

  1 internal class Program
  2 {
  3     private static void Main(string[] args)
  4     {
  5         //构建各个领导人
  6         Leader director = new Director("张三");//主任
  7         Leader manager = new Manager("李四");//经理
  8         Leader generalManager = new GeneralManager("王五");//总经理
  9         //设置各个责任链上的关系
 10         director.setNextLeader(manager);//主任的下一个审批人为经理
 11         manager.setNextLeader(generalManager);//经理的下一个审批人为总经理
 12
 13         //开始请假
 14         LeaveRequest request = new LeaveRequest("小明", 5, "旅游");
 15         director.HandleRequest(request);//小明提交了请假申请给主任
 16     }
 17 }
 18
 19 /// <summary>
 20 /// 请假的信息
 21 /// </summary>
 22 public class LeaveRequest
 23 {
 24     public string EmplName { get; set; }
 25     public int LeaveDays { get; set; }
 26     public string Reason { get; set; }
 27
 28     public LeaveRequest(string emplName, int leaveDays, string reason)
 29     {
 30         this.EmplName = emplName;
 31         this.LeaveDays = leaveDays;
 32         this.Reason = reason;
 33     }
 34 }
 35
 36 /// <summary>
 37 /// 管理责任链上的对象处理的抽象类
 38 /// </summary>
 39 public abstract class Leader
 40 {
 41     protected string name;
 42     protected Leader nextLeader;//下一个继承者
 43
 44     public Leader(string name)
 45     {
 46         this.name = name;
 47     }
 48
 49     /// <summary>
 50     /// 设置责任链上的下一个继承者
 51     /// </summary>
 52     /// <param name="leader"></param>
 53     public void setNextLeader(Leader leader)
 54     {
 55         this.nextLeader = leader;
 56     }
 57
 58     /// <summary>
 59     /// 处理请求的抽象方法
 60     /// </summary>
 61     /// <param name="leader"></param>
 62     public abstract void HandleRequest(LeaveRequest leader);
 63 }
 64
 65 /// <summary>
 66 /// 主任: 处理小于等于3天的假期
 67 /// </summary>
 68 public class Director : Leader
 69 {
 70     public Director(string name)
 71         : base(name)
 72     {
 73     }
 74
 75     /// <summary>
 76     /// 责任链上对象对请求的具体处理
 77     /// </summary>
 78     /// <param name="leader"></param>
 79     public override void HandleRequest(LeaveRequest leader)
 80     {
 81         if (leader.LeaveDays <= 3)
 82         {
 83             Console.WriteLine($"请假人:{leader.EmplName},天数{leader.LeaveDays},理由:{leader.Reason}");
 84             Console.WriteLine($"审批人:{this.name } 主任,审批通过!");
 85         }
 86         else
 87         {
 88             if (this.nextLeader != null)
 89             {
 90                 this.nextLeader.HandleRequest(leader);
 91             }
 92         }
 93     }
 94 }
 95
 96 /// <summary>
 97 /// 经理: 处理大于3天,小于等于10天的假期
 98 /// </summary>
 99 public class Manager : Leader
100 {
101     public Manager(string name)
102         : base(name)
103     {
104     }
105
106     /// <summary>
107     /// 责任链上对象对请求的具体处理
108     /// </summary>
109     /// <param name="leader"></param>
110     public override void HandleRequest(LeaveRequest leader)
111     {
112         if (leader.LeaveDays > 3 && leader.LeaveDays <= 10)
113         {
114             Console.WriteLine($"请假人:{leader.EmplName},天数{leader.LeaveDays},理由:{leader.Reason}");
115             Console.WriteLine($"审批人:{this.name } 经理,审批通过!");
116         }
117         else
118         {
119             if (this.nextLeader != null)
120             {
121                 this.nextLeader.HandleRequest(leader);
122             }
123         }
124     }
125 }
126
127 /// <summary>
128 /// 总经理: 处理大于10天,小于等于30天的请假信息
129 /// </summary>
130 public class GeneralManager : Leader
131 {
132     public GeneralManager(string name)
133         : base(name)
134     {
135     }
136
137     /// <summary>
138     /// 责任链上对象对请求的具体处理
139     /// </summary>
140     /// <param name="leader"></param>
141     public override void HandleRequest(LeaveRequest leader)
142     {
143         if (leader.LeaveDays > 10 && leader.LeaveDays <= 30)
144         {
145             Console.WriteLine($"请假人:{leader.EmplName},天数{leader.LeaveDays},理由:{leader.Reason}");
146             Console.WriteLine($"审批人:{this.name } 总经理,审批通过!");
147         }
148         else
149         {
150             if (this.nextLeader != null)
151             {
152                 this.nextLeader.HandleRequest(leader);
153             }
154             else
155             {
156                 Console.WriteLine($"你疯了!!!");
157             }
158         }
159     }
160 }

  从实现上可以看出,每个领导只处理自己能力范围内的事情,不是自己的坚决不处理;同时职责链是动态构建的,下一个处理者由调用者自己设置;缺少处理对象可以直接添加,符合开闭原则。

职责链的优缺点:

  优点:

    1)请求者和接收者松耦合。在职责链模式中,请求者并不知道接收者是谁,也不知道具体如何处理,请求者只是负责向职责链发送请求就可以了。而每个职责对象也不用管请求者或者是其他的职责对象,只负责处理自己的部分,其他的就交给其他的职责对象去处理。也就是说,请求者和接受者是完全解耦的。

    2)动态组合职责。职责链模式会把功能处理分散到单独的职责对象中,然后再使用的时候,可以动态组合职责形成职责链,从而可以灵活地给对象分配职责,也可以灵活地实现和改变对象的职责。

    3)减少代码中的if..else..判断,优化代码。

  缺点:

    1)产生很多细粒度对象。职责链模式会把功能处理分散到单独的职责对象中,也就是每个职责对象只处理一个方面的功能,要把整个业务处理完,需要很多职责对象的组合,这样会产生大量的细粒度职责对象。

    2)不一定能被处理。职责链模式的每个职责对象只负责自己处理的那一部分,因此可能会出现某个请求把整个链传递完了都没有职责对象处理它。这就需要使用职责链模式的时候,需要提供默认的处理,并且注意构造的链的有效性。

    3)职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

职责链的应用场景:

  1)有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。

  2)可动态指定一组对象处理请求,或添加新的处理者。

  3)在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

参考:https://www.cnblogs.com/cxxjohnson/p/6403849.html

原文地址:https://www.cnblogs.com/az4215/p/11621948.html

时间: 2024-08-03 01:48:46

设计模式-行为型-职责链模式的相关文章

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就推卸给另外个一个部门(对象).至于究竟谁来解决问题呢?政府部门就是为了能够避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,而且沿着这条链传递请求.直到有(部门)对象处理它为止. 样例1:js的事件浮升机制 样例2: 2.问题 假设有多个对象都有

编程模式之十四----行为型----职责链模式

定义 避免把一个请求的发送者和接收者耦合在一起,使多个对象都有机会处理请求.将这个请求的多个接收着连接成一条链,并让请求沿着这个链传递下去,只到有一个结点能处理请求. 职责链模式中,链形成后,不一定非要有一个结点能够处理请求,也就是说,所有结点都可以处理一下再往下传,也可以都不处理,这样说来就比较灵活了. 组成 抽象处理者:AbstractHandler.维护一个对自身类型对象的引用,这个引用作为下一个具体的处理者.声明所有处理者都用到的方法,这个方法的作用是设置本处理者后面的一个处理者.另外声

[设计模式-行为型]责任链模式(Chain of Responsibility)

概括 名称 Chain of Responsibility 结构 动机 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 适用性 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定. 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求. 可处理一个请求的对象集合应被动态指定. 解析 形象比喻: 晚上去上英语课, 为了好开溜坐到了最后一排, 哇, 前面坐了好几个漂亮的MM 哎

设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)

1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,并且沿着这条链传递请求,直到有(部门)对象处理它为止. 例子1:js的事件浮升机制 例子2: 2.问题 如果有多个对象都有可能接受请求,如何避免避免请求发送者与接收者耦合在一起呢? 3.解决方案 职责链模式(Ch

设计模式-行为型-职责链设计模式

一.简介 职责链设计模式是属于经典设计模式中行为型设计模式里的一种设计模式.其实这种模式 在现实生活中很多地方出现,比如说: 1.多人打牌: 上家出牌后,出牌请求到达下家,下家出牌后,下下家获得出牌机会, 在一轮后如果无人出牌,则可以从 新下一轮出牌,这样一个场景,其实就是职责链模式的原型. 2.审批流程: 再比如,一个公司的采购单审批流程,如果采购单总价在5万RMB,那么主任审核即可, 如果5-10万RMB 由副董事长审批,10-50万由董事长审批,>=50万则由董事会审批.每一个节点只负责职

大话设计模式Python实现-职责链模式

职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系.将对象连成链并沿着这条链传递请求直到被处理 下面是一个设计模式的demo: 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 __author__ = 'Andy' 5 """ 6 大话设计模式 7 设计模式--职责链模式 8 职责链模式(Chain Of Responsibility):使多个对象

设计模式入门之职责链模式Chain Of Responsibility

//职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. //实例:申请费用的功能,不同金额的费用须要由不同的上级部分审核通过,假设下级没有审核的权限那么就让上级来进行审核 //上代码 //定义职责对象的接口 public abstract class Handler { protected Handler successor = null; public Handler(Handler su

设计模式学习之职责链模式

1.定义: 职责连模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这个对象练成一条链,并沿着链传递该请求,直到由一个对象处理它为止. 2.UML ConcreteHandler1.ConcreteHandler2 :具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给他的后继者. 3.职责链的好处 关键在与当客户提交一个请求时,请求是沿着链传递直至由一个Concrea

设计模式学习笔记--职责链模式

1 using System; 2 3 namespace ChainOfResponsibility 4 { 5 /// <summary> 6 /// 作者:bzyzhang 7 /// 时间:2016/6/1 6:54:00 8 /// 博客地址:http://www.cnblogs.com/bzyzhang/ 9 /// Handler说明:本代码版权归bzyzhang所有,使用时必须带上bzyzhang博客地址 10 /// </summary> 11 public ab