职责链模式 Responsibility of Chain

在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

职责链模式的意图

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

职责链模式的结构

参与者

  • Handler——定义一个处理请求的接口。如果需要,接口可以定义一个方法,以设定和返回对下家的引用。这个角色通常由一个JAVA抽象类或者JAVA接口实现。其示意性类图如下图所示。图中的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。



  • ConcreteHandler——处理它所负责的请求。
                              ——可访问它的后继者
                              ——如果可处理该请求,就处理;否则将该请求转发给它的后继者
  • Client——向链上的具体处理者对象提交请求

协作

当客户提交一个请求时,请求沿链传递直至有一个ConcreteHandler 对象负责处理它。

使用场景

职责链可能是一条直线、一个环链或者一个树结构的一部分。为了方便,我们使用一个简单的例子。公司人事的请假流程:请假一天组长批了即可、两到三天项目经理批了即可、三天以上需总经理批准。我们来看看源码实现:

//抽象处理角色:

package headfirst.ChainOfResponsibility;

/**
* @author Nick Lau
* 抽象处理角色
*/
public abstract class Handler {
//持有处理请求的对象
protected Handler successor = null; //取得后继者
public Handler getSuccessor() {
return successor;
} //设置下一个处理请求的对象
public void setSuccessor(Handler successor) {
this.successor = successor;
} /**
* @param role 角色
* @param days 请假天数
* @return 审批成功或失败后返回的提示
*/
public abstract String handleRequest(String role, int days);
}

下面是具体处理者的示意性源码。显然,处理者的逻辑非常简单,如果一个具体处理者有下家,就将请求传递给下家;如果没有下家,就处理掉。

package headfirst.ChainOfResponsibility;

/**
* @author Nick Lau
* TeamLeader处理请假事项
*/
public class TeamLeader extends Handler { @Override
public String handleRequest(String role, int days) {
// TODO Auto-generated method stub
String tips = "";
if (days == 1) {
if ("TeamLeader".equals(role)) {
tips = "TeamLeader agree " + days + " day(s) leave.";
} else {
tips = "请假1天TeamLeader批准即可。";
}
} else {//传递给下一个继承者处理
if (getSuccessor() != null)
return getSuccessor().handleRequest(role, days);
}
return tips;
} }
package headfirst.ChainOfResponsibility;

public class ProjectManager extends Handler {

    @Override
public String handleRequest(String role, int days) {
// TODO Auto-generated method stub
String tips = "";
if (days > 1 && days <=3) {
if ("ProjectManager".equals(role)) {
tips = "ProjectManager agree " + days + " day(s) leave.";
} else {
tips = "请假1天TeamLeader批准即可;4天以上需总经理批准!";
}
} else {//如果还有下一个处理者则传递给下一个继承者处理
if (getSuccessor() != null)
return getSuccessor().handleRequest(role, days);
}
return tips;
} }
package headfirst.ChainOfResponsibility;

public class GeneralManager extends Handler{

    @Override
public String handleRequest(String role, int days) {
// TODO Auto-generated method stub
String tips = "";
if (days > 3) {
if ("GeneralManager".equals(role)) {
tips = "GeneralManager agree " + days + " day(s) leave.";
} else {
tips = role + "无权限处理" + days + "天请假事宜。";
}
} else {//传递给下一个继承者处理
if (getSuccessor() != null)
return getSuccessor().handleRequest(role, days);
}
return tips;
} }

当然,在大多数情况下,这么简单的处理逻辑是没有实际用途的。真实的处理逻辑和所研究的系统商业逻辑密切相关,这里使用最简化的商业逻辑,有助于我们将精力集中到如何将模式应用到设计中去。

客户端的源码清单如下:

package headfirst.ChainOfResponsibility;

public class Client {

    /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Handler teamLeader = new TeamLeader();
Handler projectManager = new ProjectManager();
Handler generalManager = new GeneralManager();
teamLeader.setSuccessor(projectManager);
projectManager.setSuccessor(generalManager); String test1 = teamLeader.handleRequest("TeamLeader", 1);
System.out.println(test1);
String test2 = teamLeader.handleRequest("ProjectManager", 1);
System.out.println(test2);
System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++\n"); String test3 = teamLeader.handleRequest("ProjectManager", 3);
System.out.println(test3);
String test4 = teamLeader.handleRequest("GeneralManager", 3);
System.out.println(test4);
System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++\n"); String test5 = teamLeader.handleRequest("ProjectManager", 11);
System.out.println(test5);
String test6 = teamLeader.handleRequest("GeneralManager", 11);
System.out.println(test6);
System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++\n");
} }

客户端输出如下:

TeamLeader agree 1 day(s) leave.
请假1天TeamLeader批准即可。
+++++++++++++++++++++++++++++++++++++++++++++++++
ProjectManager agree 3 day(s) leave.
请假1天TeamLeader批准即可;4天以上需总经理批准!
+++++++++++++++++++++++++++++++++++++++++++++++++
ProjectManager无权限处理11天请假事宜。
GeneralManager agree 11 day(s) leave.
+++++++++++++++++++++++++++++++++++++++++++++++++

效果

职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。一个链可以是一条线、一棵树、也可以是一个环。链的拓扑结构可以是单连通的或多连通的,职责链模式并不指定职责链的拓扑结构。但是职责链模式要求在同一个时间里,命令只可以被传给一个下家(或被处理掉)而不能传给多个下家。

下面情况可以使用职责链模式:

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

OOP设计模式[JAVA]——03职责链模式的更多相关文章

  1. Java设计模式之《职责链模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6530089.html 职责链模式(称责任链模式)将请求的处理对象像一条长链一般组合起来,形 ...

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

     设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...

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

     设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...

  4. java 之 职责链模式(大话设计模式)

    目前很多OA办公自动化软件,加快了办公效率,简化流程.相信很多小伙伴都用过.笔者了解到的大多数办公软件底层实现流程大多数采用的都是Activity或者是JBPM框架. 今天笔者要说的也是类似于流程的一 ...

  5. java设计模式-----18、职责链模式

    概念: Chain of Responsibility(CoR)模式也叫职责链模式.责任链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的 ...

  6. JAVA设计模式之【职责链模式】

    职责链模式 专门处理请求链式传递的模式 角色 Handler抽象处理者 ConcreteHandler具体处理者 在职责链模式中,很多对象由每一个对象对其下家的引用而连接成一条链,请求在这条链上传递, ...

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

    职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系.将对象连成链并沿着这条链传递请求直到被处理 下面是一个设计模式的demo: ...

  8. C#设计模式系列:职责链模式(Chain of Responsibility)

    1.职责链模式简介 1.1>.定义 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对 ...

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

    //职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. //实例:申请费用的功能,不同金额的费 ...

随机推荐

  1. CodePage代码,MultiByteToWideChar

    Identifier .NET Name Additional information 37 IBM037 IBM EBCDIC US-Canada 437 IBM437 OEM United Sta ...

  2. .NET Framework个版本说明

    .NET Framework .NET版本 1.0 1.1 2.0 3.0 3.5 4.0 4.5 完整版本 1.0.3705.0 1.1.4322.573 2.0.50727.42 3.0.4506 ...

  3. Domain Name System (DNS)

    1.DNS和WINS的作用 DNS:(Domain Name Server,域名服务)用于实现域名和IP地址的相互转换. WINS:(Windows Internet Name Service) 用来 ...

  4. 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制

    libs/android_runtime/android_net_wifi_Wifi.cpp部分jni接口static JNINativeMethod gWifiMethods[] = {{ &quo ...

  5. 《Python 学习手册4th》 第十六章 函数基础

    ''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...

  6. 我喜欢的乐队-Euphoria

    来自日本的后摇乐团,001年冬天由森川裕之.佐藤昭太.木下阳辅三人于东京组建,2003年签约日本独立厂牌123Record,并发行首张EP细碟<Floral Dew>.包括EP.Singl ...

  7. bzoj1150

    haha,贪心,边界条件折腾了我一会儿 #include<cstdio> #include<cctype> #include<queue> #include< ...

  8. oracle检查点checkpoint信息

    1.关于checkpoint的概述 checkpoint是oracle在数据库一致性关闭.实例恢复和oracle基本操作中不可缺少的机制,包含以下相关的含义: A.检查点的位置(checkpoint ...

  9. CSS:不可思议的border属性

    原文:Magic of CSS border property 译文:不可思议的CSS border属性 译者:dwqs 在CSS中,其border属性有很多的规则.对于一些事物,例如三角形或者其它的 ...

  10. bzoj 3629 [JLOI2014]聪明的燕姿(约数和,搜索)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3629 [题意] 给定S,找出所有约数和为S的数. [思路] 若n=p1^a1*p2^a ...