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

简单的应用举例:

参考文章:

http://blog.csdn.net/jason0539/article/details/45091639

http://www.cnblogs.com/kym/archive/2009/04/06/1430078.html

请假这个事情,相信每个人都不陌生。

在公司里,如果请假时间小于0.5天,那么只需要向项目经理打声招呼就OK了。

如果超过了0.5天,但是还小于2天,那么就要去找人事部处理,当然,这就要扣工资了。

如果超过了2天,你就需要去找总经理了,工资当然也玩完了。

那么,对于我们来说,这个流程就是这样的。

也就是这样一个过程,你需要和你的直接上级——项目经理去打交道,最终可能是项目经理给你回邮件,可能是人事部给你回邮件,也可能是总经理给你回邮件。内部的过程其实应该是个黑盒子,你并不知道内部的消息是如何处理的。你需要找到的,只是你想要第一个交付的对象而已。

借上面的例子解释下什么是责任链模式?

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

即员工请假时向上层传递请求,上级(项目经理,部门经理,hr)都可以选择处理这个请求或者指定处理对象。直到这个请求被处理为止。

UML图

参与者:

Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。

ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。

Client: 客户类。

职责链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。

避 免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是职责链模 式。在职责链模式中,使得每一个对象都有可能来处理请求,从而实现了请求的发送者和接收者之间的解耦。同时职责链模式简化了对象的结构,它使得每个对象都 只需要引用它的后继者即可,而不必了解整条链,这样既提高了系统的灵活性也使得增加新的请求处理类也比较方便。但是在职责链中我们不能保证所有的请求都能 够被处理,而且不利于观察运行时特征。

代码举例:

抽象的Handle角色:

 1 public abstract class Handler {
 2
 3     /**
 4      * 持有后继的责任对象
 5      */
 6     protected Handler successor;
 7     /**
 8      * 示意处理请求的方法,虽然这个示意方法是没有传入参数的
 9      * 但实际是可以传入参数的,根据具体需要来选择是否传递参数
10      */
11     public abstract void handleRequest();
12     /**
13      * 取值方法
14      */
15     public Handler getSuccessor() {
16         return successor;
17     }
18     /**
19      * 赋值方法,设置后继的责任对象
20      */
21     public void setSuccessor(Handler successor) {
22         this.successor = successor;
23     }
24
25 }

具体处理者角色:

 1 public class ConcreteHandler extends Handler {
 2     /**
 3      * 处理方法,调用此方法处理请求
 4      */
 5     @Override
 6     public void handleRequest() {
 7         /**
 8          * 判断是否有后继的责任对象
 9          * 如果有,就转发请求给后继的责任对象
10          * 如果没有,则处理请求
11          */
12         if(getSuccessor() != null)
13         {
14             System.out.println("放过请求");
15             getSuccessor().handleRequest();
16         }else
17         {
18             System.out.println("处理请求");
19         }
20     }
21
22 }

客户端类:

 1     public class Client {
 2
 3         public static void main(String[] args) {
 4             //组装责任链
 5             Handler handler1 = new ConcreteHandler();
 6             Handler handler2 = new ConcreteHandler();
 7             handler1.setSuccessor(handler2);
 8             //提交请求
 9             handler1.handleRequest();
10         }
11
12     }  

可以看出,客户端创建了两个处理者对象,并指定第一个处理者对象的下家是第二个处理者对象,而第二个处理者对象没有下家。然后客户端将请求传递给第一个处理者对象。

由于本示例的传递逻辑非常简单:只要有下家,就传给下家处理;如果没有下家,就自行处理。

因此,第一个处理者对象接到请求后,会将请求传递给第二个处理者对象。由于第二个处理者对象没有下家,于是自行处理请求。

代码示例2:申请聚餐

申请聚餐费用的管理,申请聚餐费用的大致流程一般是,由申请人先填写申请单,然后交给领导审批,如果申请批准下来,领导会通知申请人审批通过,然后申请人去财务领取费用,如果没有批准下来,领导会通知申请人审批未通过,此事也就此作罢。

不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批500元以内的申请;部门经理能审批1000元以内的申请;而总经理可以审核任意额度的申请。

当某人提出聚餐费用申请的请求后,该请求会经由项目经理、部门经理、总经理之中的某一位领导来进行相应的处理,但是提出申请的人并不知道最终会由谁来处理 他的请求,一般申请人是把自己的申请提交给项目经理,或许最后是由总经理来处理他的请求。申请人只要直接与项目经理交互就可以,其余的工作在黑盒中,究竟 流程是怎样的,最后是由谁审批通过的,申请人无需关心。

uml图:

代码:

抽象处理者角色类

 1 public abstract class Handler {
 2     /**
 3      * 持有下一个处理请求的对象
 4      */
 5     protected Handler successor = null;
 6     /**
 7      * 取值方法
 8      */
 9     public Handler getSuccessor() {
10         return successor;
11     }
12     /**
13      * 设置下一个处理请求的对象
14      */
15     public void setSuccessor(Handler successor) {
16         this.successor = successor;
17     }
18     /**
19      * 处理聚餐费用的申请
20      * @param user    申请人
21      * @param fee    申请的钱数
22      * @return        成功或失败的具体通知
23      */
24     public abstract String handleFeeRequest(String user , double fee);
25 }

具体处理者角色类

ProjectManager

 1 public class ProjectManager extends Handler {
 2
 3     @Override
 4     public String handleFeeRequest(String user, double fee) {
 5
 6         String str = "";
 7         //项目经理权限比较小,只能在500以内
 8         if(fee < 500)
 9         {
10             //为了测试,简单点,只同意张三的请求
11             if("张三".equals(user))
12             {
13                 str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
14             }else
15             {
16                 //其他人一律不同意
17                 str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
18             }
19         }else
20         {
21             //超过500,继续传递给级别更高的人处理
22             if(getSuccessor() != null)
23             {
24                 return getSuccessor().handleFeeRequest(user, fee);
25             }
26         }
27         return str;
28     }
29
30 }

DeptManager

 1 public class DeptManager extends Handler {
 2
 3     @Override
 4     public String handleFeeRequest(String user, double fee) {
 5
 6         String str = "";
 7         //部门经理的权限只能在1000以内
 8         if(fee < 1000)
 9         {
10             //为了测试,简单点,只同意张三的请求
11             if("张三".equals(user))
12             {
13                 str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
14             }else
15             {
16                 //其他人一律不同意
17                 str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
18             }
19         }else
20         {
21             //超过1000,继续传递给级别更高的人处理
22             if(getSuccessor() != null)
23             {
24                 return getSuccessor().handleFeeRequest(user, fee);
25             }
26         }
27         return str;
28     }
29
30 }

GeneralManager

 1 public class GeneralManager extends Handler {
 2
 3     @Override
 4     public String handleFeeRequest(String user, double fee) {
 5
 6         String str = "";
 7         //总经理的权限很大,只要请求到了这里,他都可以处理
 8         if(fee >= 1000)
 9         {
10             //为了测试,简单点,只同意张三的请求
11             if("张三".equals(user))
12             {
13                 str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
14             }else
15             {
16                 //其他人一律不同意
17                 str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
18             }
19         }else
20         {
21             //如果还有后继的处理对象,继续传递
22             if(getSuccessor() != null)
23             {
24                 return getSuccessor().handleFeeRequest(user, fee);
25             }
26         }
27         return str;
28     }
29
30 }

客户端类

 1 public class Client {
 2
 3     public static void main(String[] args) {
 4         //先要组装责任链
 5         Handler h1 = new GeneralManager();
 6         Handler h2 = new DeptManager();
 7         Handler h3 = new ProjectManager();
 8         h3.setSuccessor(h2);
 9         h2.setSuccessor(h1);
10
11         //开始测试
12         String test1 = h3.handleFeeRequest("张三", 300);
13         System.out.println("test1 = " + test1);
14         String test2 = h3.handleFeeRequest("李四", 300);
15         System.out.println("test2 = " + test2);
16         System.out.println("---------------------------------------");
17
18         String test3 = h3.handleFeeRequest("张三", 700);
19         System.out.println("test3 = " + test3);
20         String test4 = h3.handleFeeRequest("李四", 700);
21         System.out.println("test4 = " + test4);
22         System.out.println("---------------------------------------");
23
24         String test5 = h3.handleFeeRequest("张三", 1500);
25         System.out.println("test5 = " + test5);
26         String test6 = h3.handleFeeRequest("李四", 1500);
27         System.out.println("test6 = " + test6);
28     }
29
30 }

职责链灵活在哪

1. 改变内部的传递规则

在内部,项目经理完全可以跳过人事部到那一关直接找到总经理。

每个人都可以去动态地指定他的继任者。

2. 可以从职责链任何一关开始。

如果项目经理不在,可以直接去找部门经理,责任链还会继续,没有影响。

3.用与不用的区别

不用职责链的结构,我们需要和公司中的每一个层级都发生耦合关系。

如果反映在代码上即使我们需要在一个类中去写上很多丑陋的if….else语句。

如果用了职责链,相当于我们面对的是一个黑箱,我们只需要认识其中的一个部门,然后让黑箱内部去负责传递就好了

纯的与不纯的责任链模式

一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。

在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。

纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。

时间: 2024-10-14 14:10:13

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

设计模式(行为型)之职责链模式(Chain of Responsibility Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之状态模式(State Pattern)>http://blog.csdn.net/yanbober/article/details/45502665 概述 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链

责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)

责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 责任链模式中,每个对象通过持有对下家的引用而链接起来,形成一条链条,串联起来多个处理对象. 在责任链模式中,请求在链上进行传递,直到链上的某一个对象决定处理此请求. 发出这个请求的客户端程序并不知道到底是哪一个对象具体的处理了请求 这使得系统可以在不影响客户

atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换

atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3. 调用代码 2 4. 责任链链的特性: 2 5. 模式结构 4 6. 职责链模式包含如下角色:Handler,ConcreteHandler: 具体处理者,HandlerChainUtil ,Client 4 7. 设置哈一个handler,,两个法:排序法,指定法 5 1. 指定法 5 2. 排

&quot;围观&quot;设计模式(22)--行为型之职责链模式(Chain Of Responsibility Pattern)

责任链模式在面向对象程式设计里是一种软件设计模式,它包含了一些命令对象和一系列的处理对象.每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象.该模式还描述了往该处理链的末尾添加新的处理对象的方法.----WIKIPEDIA 个人的理解 责任链模式用到了链表的数据结构,存在一定的次序性,A->B->C这样的一条链表,在责任链模式中,请求交给A进行处理,如果A处理不了交给B,B如果处理的了进行处理,否则交给C处理,模式的关键在于构建这样的一个链表

重温设计模式(三)——职责链模式(chain of responsibility)

一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所以希望各位多多指教. 二. 什么是链 文章伊始,先让我们了解这个最基本的概念,什么是链. 我给链下了这样的定义: 1. 链是一系列节点的集合. 2. 链的各节点可灵活拆分再重组. 三. 何为职责链 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条

大战设计模式【18】&mdash;&mdash; 职责链模式

职责链模式(Chain of Responsibility) 设计模式使用的例子https://github.com/LinkinStars/DesignPatternsAllExample 一.定义 避免将请求发送者与接受者耦合在一起,让多个对象都有机会接受请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 二.结构 Handler(抽象处理者):定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法. Co

[设计模式]&lt;6&gt;. C++与职责链模式(chain of rsponsibility pattern)

默默地EEer,原文地址: http://www.cnblogs.com/hebaichuanyeah/p/5625233.html 职责链模式指使多个对象多有机会处理请求,避免请求发送者和接受者的耦合关系. 将这些接受处理的对象连成一条链,并沿着该链处理请求. 一个传说中的应用情景: 假如去政府部门办事,遇到了打字员小丽,在打LOL的小张以及主任老李,互相踢皮球推脱. #include <iostream> using namespace std; class Handler { prote

设计模式 --&gt; (15)职责链模式

职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 示例 考虑员工要求加薪.公司的管理者一共有三级,总经理.总监.经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权 内,那么经理可以直接批准,否则将申请上交给总监.总监的处理方式也一样,总经理可以处理所有请求.这就是典型的职责链模式,请求的处理形成了一条链,直 到有一个对象处理请求. #include <iostre

第15章 行为型模式—职责链模式

1. 职责链模式(Chain Of Responsibility)的定义 (1)定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. ①标准的职责链模式中,只要有对象处理了请求,这个请求就到此为至,不再被传递和处理了. ②但也可以变形使用职责链,就是让这个请求继续传递,每个职责对象对这个请求进行一定的功能处理,从而形成一个处理请求的功能链. ③当客户端发出请求,它并不知道谁会真正处理他的请求.在职责