OOP设计模式[JAVA]——03职责链模式
职责链模式 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.
+++++++++++++++++++++++++++++++++++++++++++++++++
效果
职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。一个链可以是一条线、一棵树、也可以是一个环。链的拓扑结构可以是单连通的或多连通的,职责链模式并不指定职责链的拓扑结构。但是职责链模式要求在同一个时间里,命令只可以被传给一个下家(或被处理掉)而不能传给多个下家。
下面情况可以使用职责链模式:
- 系统已经有一个由处理者对象组成的链。这个链可能由合成模式给出。
- 有多于一个的处理者对象会处理一个请求,而事先并不知道到底由哪一个处理者对象处理该请求。这个处理者对象是动态确定的。
- 系统想发出一个请求给多个处理者对象中的某一个,但是不明显指定是哪一个处理者对象。
- 处理一个请求的处理者对象集合需要动态地被指定。
OOP设计模式[JAVA]——03职责链模式的更多相关文章
- Java设计模式之《职责链模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6530089.html 职责链模式(称责任链模式)将请求的处理对象像一条长链一般组合起来,形 ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...
- java 之 职责链模式(大话设计模式)
目前很多OA办公自动化软件,加快了办公效率,简化流程.相信很多小伙伴都用过.笔者了解到的大多数办公软件底层实现流程大多数采用的都是Activity或者是JBPM框架. 今天笔者要说的也是类似于流程的一 ...
- java设计模式-----18、职责链模式
概念: Chain of Responsibility(CoR)模式也叫职责链模式.责任链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的 ...
- JAVA设计模式之【职责链模式】
职责链模式 专门处理请求链式传递的模式 角色 Handler抽象处理者 ConcreteHandler具体处理者 在职责链模式中,很多对象由每一个对象对其下家的引用而连接成一条链,请求在这条链上传递, ...
- 大话设计模式Python实现-职责链模式
职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系.将对象连成链并沿着这条链传递请求直到被处理 下面是一个设计模式的demo: ...
- C#设计模式系列:职责链模式(Chain of Responsibility)
1.职责链模式简介 1.1>.定义 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对 ...
- 设计模式入门之职责链模式Chain Of Responsibility
//职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. //实例:申请费用的功能,不同金额的费 ...
随机推荐
- 图解VS2010打包全过程
原文转自:http://blog.csdn.net/shan9liang/article/details/6957308 最近刚刚打包发布了用VS2010开发的一个收费系统,借此讲一讲打包过程,供大家 ...
- 根据中国气象局提供的API接口实现天气查询
中国气象局提供了三个天气查询的API接口: [1]http://www.weather.com.cn/data/sk/101190101.html [2]http://www.weather.com. ...
- 学习:java设计模式—工厂模式
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...
- iOS AFNetworking的使用
转:http://www.cnblogs.com/lookenwu/p/3927897.html AFNetworking几乎是iOS上最常用的HTTP库了,AFNetworking也确实用起来简单, ...
- Android之APK文件签名——keytool和jarsigner
一.生成密钥库将位置定位在jdk的bin文件中,输入以下命名行:keytool -genkey -alias ChangeBackgroundWidget.keystore -keyalg RSA - ...
- Android控件之GridView
GridView是一项显示二维的viewgroup,可滚动的网格.一般用来显示多张图片. 以下模拟九宫图的实现,当鼠标点击图片时会进行相应的跳转链接. 目录结构 main.xml布局文件,存放Grid ...
- Perfect Service
题意: n个节点树,在一个节点放上一台服务器可以给相邻的其他各点提供服务且一个节点只能接受一台服务器,求使n个节点都被服务放的服务器的最小数量. 分析: 不算太难,状态想的差不多,但是考虑不全面状态方 ...
- 基于GPL329xx linux平台电容屏gsl1680的驱动调试分析
因客户有用到了gsl1680 7寸电容屏,所以拿了一块过来,便在329xx的平台上面开始调试了. 大概浏览了一下所提供的资料,只有介绍模组的资料跟一份中文版的datasheet,datasheet只是 ...
- Aggregation(1):Blending、Bagging、Random Forest
假设我们有很多机器学习算法(可以是前面学过的任何一个),我们能不能同时使用它们来提高算法的性能?也即:三个臭皮匠赛过诸葛亮. 有这么几种aggregation的方式: 一些性能不太好的机器学习算法(弱 ...
- JSON 省市数据包括港澳
data: [{ name: "北京", cities: ["西城", "东城", "崇文", "宣武&quo ...