博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

责任链模式

简介

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

责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心。

责任链就是从一个起点发起请求,然后沿着任务链依次传递给每一个节点上的对象,直到有一个节点处理这个请求为止。

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

现实中最适合责任链的应该就是部门领导之间的上报请求了。比如员工要申请一笔资金,会先向组长申请,额度如果在组长的范围内,组长就批了,组长权限不够就向主管申请,主管如果也额度不够就向经理申请。这就形成了个责任链。

组长,主管,经理。每个人都是责任链上的一个节点。一个请求被层层转达,直到被处理或没有一个人能处理。普通员工,就是那个申请的发起者,并不需要知道到底最后是谁审批的,他只要拿到钱就行了。这样就造成了请求者和处理者的解耦。

责任链有一个缺点是,大家在开发的时候要注意,调试不是很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。

适用性

  • 有多个对象可以处理一个请求,具体哪个对象处理该请求在运行时刻自动确定。
  • 在请求的处理者不明确的情况下,向多个对象的一个提交请求。
  • 需要动态指定一组对象处理请求。

角色

  • Handler:抽象处理者角色,声明一个处理请求的方法,并保持对下一个处理节点Handler对象的引用。
  • ConcreteHandler: 具体的处理者,对请求进行处理,如果不处理就讲请求转发给下一个节点上的处理对象。

作用:请求会被链上的对象处理,但是客户端不知道请求会被哪些对象处理 
通过把请求从一个对象传递到链条中下一个对象的方式,直到请求被处理完毕,以实现对象间的解耦。

JDK中体现:ClassLoader的委托模型

简单版案例

抽象处理者

public abstract class Handler {
protected Handler successor;
public abstract void handleRequest(String condition);
}

实际处理者1

public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if ("ConcreteHandler1".equals(condition)){
System.out.println("ConcreteHandler1 handled");
}else {
successor.handleRequest(condition);
}
}
}

实际处理者2

public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if ("ConcreteHandler2".equals(condition)) {
System.out.println("ConcreteHandler2 handled");
} else {
successor.handleRequest(condition);
}
}
}

客户端调用

组成一条责任链

public class Client {
public static void main(String[] args) {
ConcreteHandler1 concreteHandler1 = new ConcreteHandler1();
ConcreteHandler2 concreteHandler2 = new ConcreteHandler2();
concreteHandler1.successor = concreteHandler2;
concreteHandler2.successor = concreteHandler1; concreteHandler1.handleRequest("ConcreteHandler2");
}
}

简单版中,传递的都是统一的字符串,处理也比较简单。但是在实际开发中,责任链中的请求处理规则是不尽相同的,这种时候需要对请求进行封装,同时对请求的处理规则也进行一个封装,

复杂版案例

抽象处理者

public abstract class AbstractHandler {
protected AbstractHandler nextHandler; public final void handleRequest(AbstractRequest request){
if (request.getRequestLevel()==getHandleLevel()){
handle(request);
}else {
if (nextHandler!=null){
nextHandler.handleRequest(request);
}else {
System.out.println("没有对象能处理这个请求");
}
}
}
protected abstract int getHandleLevel();
protected abstract void handle(AbstractRequest request);
}

三个处理者

public class Handler1 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 1;
} @Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1处理了请求:"+request.getRequestLevel());
}
}
public class Handler2 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 2;
} @Override
protected void handle(AbstractRequest request) {
System.out.println("Handler2处理了请求:"+request.getRequestLevel());
}
}
public class Handler3 extends AbstractHandler {
@Override
protected int getHandleLevel() {
return 3;
} @Override
protected void handle(AbstractRequest request) {
System.out.println("Handler3处理了请求:"+request.getRequestLevel());
}
}

抽象请求者

public abstract class AbstractRequest {
private Object obj;
public AbstractRequest(Object obj){
this.obj=obj;
}
public Object getContent(){
return obj;
}
public abstract int getRequestLevel();
}

实现的三个请求

public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
} @Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
} @Override
public int getRequestLevel() {
return 2;
}
}
public class Request3 extends AbstractRequest {
public Request3(Object obj) {
super(obj);
} @Override
public int getRequestLevel() {
return 3;
}
}

客户端调用

public class Client {
public static void main(String[] args) {
//构造三个处理对象
AbstractHandler handler1 = new Handler1();
AbstractHandler handler2 = new Handler2();
AbstractHandler handler3 = new Handler3();
//串成一个责任链
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
//构造三个请求
AbstractRequest request1 = new Request1("A");
AbstractRequest request2 = new Request2("B");
AbstractRequest request3 = new Request3("C"); handler1.handleRequest(request1);
handler1.handleRequest(request2);
handler1.handleRequest(request3);
}
}

实际案例

抽象的领导

public abstract class Leader {
protected Leader nextLeader; public final void handleRequest(int money) {
if (money < = getLimit()) {
handle(money);
} else {
if (nextLeader != null) {
nextLeader.handleRequest(money);
} else {
System.out.println(money + "没人能批准");
}
}
} public abstract int getLimit(); public abstract void handle(int money);
}

三个具体的领导

public class GroupLeader extends Leader {
@Override
public int getLimit() {
return 5000;
} @Override
public void handle(int money) {
System.out.println(money + "由组长批准");
}
}
public class Director extends Leader {
@Override
public int getLimit() {
return 10000;
} @Override
public void handle(int money) {
System.out.println(money + "由主管批准");
}
}
public class Manager extends Leader {
@Override
public int getLimit() {
return 20000;
} @Override
public void handle(int money) {
System.out.println(money + "由经理批准");
}
}

员工申请

public class Test {
public static void main(String[] args) {
Leader groupLeader = new GroupLeader();
Leader director = new Director();
Leader manager = new Manager();
groupLeader.nextLeader = director;
director.nextLeader = manager; groupLeader.handleRequest(4000);
groupLeader.handleRequest(12000);
groupLeader.handleRequest(30000);
}
}

2016-04-21

Chain of Responsibility 责任链模式 MD的更多相关文章

  1. 设计模式(13)--Chain of Responsibility(责任链模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...

  2. Chain of Responsibility 责任链模式

    简介 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其[下家]的引用而连接起来形成一条链,请求在这个链上[传递],直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  3. 设计模式(一)Chain Of Responsibility责任链模式

    设计模式篇章,源于网课的学习,以及个人的整理 在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的 1.定义一个类 public class MsgProcesser { ...

  4. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  5. 设计模式C++学习笔记之十七(Chain of Responsibility责任链模式)

      17.1.解释 概念:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. main(),客户 IWom ...

  6. Chain of Responsibility - 责任链模式

    定义 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合度. 案例 比方如今有一个图形界面,它包含一个应用Application类,一个主窗体Window,一个buttonButton ...

  7. 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)

    Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...

  8. Design Pattern Chain of Reponsibility 责任链模式

    本程序实现一个责任链模式查询人名的资料. 開始都是查询第一个人,问其是否有某人的资料,假设有就返回结果,假设没有第一个人就会询问第二个人,第二个人的行为和第一个人的行为一致的,然后一致传递下去,直到找 ...

  9. 设计模式学习笔记——Chain of Responsibility职责链模式

    重点在链.一条链,如果本节点处理不了,则传递给下一个节点处理. 关键是如何传给下一个节点? 主要是由本节点决定传给哪一个节点. public class Client { public static ...

随机推荐

  1. CentOS7启动流程

    同样我也找了一张CentOS7的启动流程图. 第一步.硬件启动阶段 这一步和CentOS6差不多,详细请看CentOS6启动流程(含详细流程图) 第二步.GRUB2引导阶段 从这一步开始,CentOS ...

  2. hdu 1325 判断有向图是否为树

    题意:判断有向图是否为树 链接:点我 这题用并查集判断连通,连通后有且仅有1个入度为0,其余入度为1,就是树了 #include<cstdio> #include<iostream& ...

  3. [OpenGL]纹理贴图实现 总结

    实现步骤 第一步:设置所需要的OpenGL环境 设置上下文环境 删除已经存在的渲染的缓存 设置颜色缓存 设置帧缓存 清除缓存 设置窗口大小 开启功能 编译shander 使用program 获取sha ...

  4. HDU 5715 XOR 游戏 二分+字典树

    XOR 游戏 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5715 Description 众所周知,度度熊喜欢XOR运算(XOR百科). 今天,它 ...

  5. PAT甲级1114. Family Property

    PAT甲级1114. Family Property 题意: 这一次,你应该帮我们收集家族财产的数据.鉴于每个人的家庭成员和他/她自己的名字的房地产(房产)信息,我们需要知道每个家庭的规模,以及他们的 ...

  6. MVC之Global.asax解析

    大家看到上面的代码了,Application_Start大家都知道这是应用程序启动入口. AreaRegistration.RegisterAllAreas是什么呢? 我们先看看微软官方的注解: 我们 ...

  7. LR下监控windows系统资源方法

    1.          通过客户端与服务器进行网络测试,保证通信畅通.(测试主机本身) 2.          在运行中输入,service.msc打开系统的服务设置,开启服务器端Windows中的如 ...

  8. IO流-递归遍历目录下指定后缀名结尾的文件名称

    /* *自定义遍历目录下指定后缀名结尾文件的名称的方法: * * param file:指定目录 name:指定后缀名 */ 1 public static void FileName(File fi ...

  9. Git_删除文件

    在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交: $ git add test.txt $ git commit -m "add test. ...

  10. Android开发点点滴滴——一些基础的但实用的知识(2)

    1.onItemLongClick和onItemClick事件截取 当须要同一时候获得一个listview的条目长按事件(onItemLongClick)和点击事件(onItemClick)时,仅仅须 ...