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
//职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. //实例:申请费用的功能,不同金额的费 ...
随机推荐
- poj 1330 Nearest Common Ancestors(LCA:最近公共祖先)
多校第七场考了一道lca,那么就挑一道水题学习一下吧= = 最简单暴力的方法:建好树后,输入询问的点u,v,先把u全部的祖先标记掉,然后沿着v->rt(根)的顺序检查,第一个被u标记的点即为u, ...
- HDU 5289 Assignment (数字序列,ST算法)
题意: 给一个整数序列,多达10万个,问:有多少个区间满足“区间最大元素与最小元素之差不超过k”.k是给定的. 思路: 如果穷举,有O(n*n)复杂度.可以用ST算法先预处理每个区间最大和最小,O(n ...
- hdu 1211 RSA
// 表示题目意思我是理解了蛮久 英语太水了 //首先这是解密公式 m=c^d mod n// 给你 p q e 然后 n=p*q fn=(p-1)*(q-1)// 给你 e,根据公式 e*d mod ...
- [Papers]NSE, $\p_3u$, Lebesgue space [Kukavica-Ziane, JMP, 2007]
$$\bex \p_3\bbu\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=2,\quad \frac{9}{4}\leq q\leq ...
- iOS 7 自定义Back按钮 与 Pop interactive gesture 问题
1.自定义Back按钮 iOS中很多时候我们都会自定义返回按钮,也是一件easy的事,类似如下: // 返回按钮 1 - (void)showNavBackButton { UIButton *bac ...
- http://blog.csdn.net/jbb0403/article/details/42102527
http://blog.csdn.net/jbb0403/article/details/42102527
- web自动化框架之三获取数据库值与界面值比较~~
数据库用到的是mysql,框架涉及数据库,主要包含两个方面,一个是每个案例执行完毕后,插入案例相关信息与数据:一个是web界面数据核对的时候,需要从sql中获取某行某列值与界面某个值做比较. 描述:w ...
- [原创]谷歌插件 - YE启动助手(YeLauncher)
版本:v1.1 更新时间:2013/11/01 * 代码完善 + 右键关于显示当前版本号,点击并链接到软件帮助页 版本:v1.0 更新时间:2013/10/20 + 插件原型
- MVC & MVVM
什么是MVC,什么是MVVM? 面向过程 --> 面向对象 --> MVC --> MV* 面向过程: 开发人员按照需求逻辑顺序开发代码逻辑,主要思维模式在于如何实现.先细节,后整体 ...
- Designing Evolvable Web API with ASP.NET 随便读,随便记 “The Internet,the World Wide Web,and HTTP”
1982年,诞生了 Internet; 1989年,诞生了World Wide Web . "World Wide Web"的构造为主要由 三部分构成: resources 资源 ...