责任链模式,顾名思义,就是一条链。这个链到底是怎么运行的呢?它主要是将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象进行处理,以此类推。 
  比如说公司请假需要审批,举个不恰当的例子,如果请假小于3天,主管审批;3-10天的,经理审批;10-30天的,总经理审批;超过30天的,不批准等等。这就得一步步去判断,如果撇开设计模式不看的话,那么我们可以使用if…else…把它解决了,但是问题可想而知,实际中的复杂程度时远远超过这个例子的。 
  下面使用责任链模式来实现一下这个场景,先来看一下它们之间的关系结构: 
 
  Leader是个抽象类,里面有个方法是获取下一个Leader,Director、Manager和GeneralManager分别继承这个抽象类。LeaveRequest中封装了请假的相关信息。下面来实现一下这个责任链模式。 
首先是封装请假信息的类:

/**
* @Description 封装请假的基本信息
* @author shanheyongmu
*
*/
public class LeaveRequest { private String name;
private int leaveDays;
private String reason; public LeaveRequest(String name, int leaveDays, String reason) {
super();
this.name = name;
this.leaveDays = leaveDays;
this.reason = reason;
}
//省略get和set方法
}

然后就是定义Leader这个抽象类了

/**
* @Description 领导的抽象类
* @author shanheyongmu
*
*/
public abstract class Leader { protected String name;
protected Leader nextLeader; //责任链上的后继对象,即这个对象无法处理,就转移给下一个Leader public Leader(String name) {
super();
this.name = name;
}
// 设定责任链上的后继对象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
} /**
* 处理请求的核心的业务方法
* 需要不同继承该类的领导自己实现
*/
public abstract void handleRequest(LeaveRequest request); }

主管、经理和总经理都需要继承该类,并实现处理请假的这个方法。

/**
* @Description 主任
* @author shanheyongmu
*
*/
public class Director extends Leader { public Director(String name) {
super(name);
} @Override
public void handleRequest(LeaveRequest request) { int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由 if(days <= 3) { //如果满足3天内的要求,主任直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("主任" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,主任" + this.name + "没法处理");
if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
}
}
} }
/**
* @Description 经理
* @author shanheyongmu
*
*/
public class Manager extends Leader { public Manager(String name) {
super(name);
} @Override
public void handleRequest(LeaveRequest request) { int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由 if(days <= 10) { //如果满足10天内的要求,经理直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("经理" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,经理" + this.name + "没法处理");
if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
}
}
} }
/**
* @Description 总经理
* @author shanheyongmu
*
*/
public class GeneralManager extends Leader { public GeneralManager(String name) {
super(name);
} @Override
public void handleRequest(LeaveRequest request) { int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由 if(days <= 30) { //如果满足30天内的要求,总经理直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("总经理" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,总经理" + this.name + "没法处理");
if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
} else {
System.out.println("请假不成功");
}
}
} }

由此可见,他们处理请求的条件是不同的,而且只要不是自己处理范围之内的,就会将请求传给链上的下一位来处理。接下来写个客户端模拟下:

public class Client {

    public static void main(String[] args) {

        Leader director = new Director("张三");
Leader manager = new Manager("李四");
Leader gManager = new GeneralManager("王五"); // 组织好责任链对象的关系
director.setNextLeader(manager);
manager.setNextLeader(gManager); // 开始请假操作
LeaveRequest request = new LeaveRequest("山河君", 15, "度假");
director.handleRequest(request);
} }

运行结果:

请假天数过多 主任张三没法处理
请假天数过多,经理李四没法处理
员工山河君请假15天,理由: 度假
总经理王五审批通过

  在实际中,设置这个链可以放到配置文件中,可以直接修改配置文件即可,这个责任链模式扩展性也很好,比如现在有个副经理,专门处理10-20天的请假,那么我只要新添加一个副经理类即可,然后在责任链上配置一下就行了,对其他的类没有影响。 
  责任链模式使用的地方很多,比如我们常见的try…catch…就是,可以有多个catch,一个个往下判断;再比如servlet里面的过滤器,就是一个责任链;再比如struts2中的拦截器,也是使用的责任链模式。

【java设计模式】之 责任链(chain of resposibility)模式的更多相关文章

  1. java设计模式之责任链模式(Chain of Responsibility)

    转自:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 在阎宏博士的<JAVA与模式>一书中开头是这样 ...

  2. Java设计模式之责任链设计模式

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

  3. JAVA设计模式之责任链模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  4. 详解java设计模式之责任链模式

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt175 从击鼓传花谈起 击鼓传花是一种热闹而又紧张的饮酒游戏.在酒宴上宾客依次 ...

  5. Java设计模式之八 ----- 责任链模式和命令模式

    前言 在上一篇中我们学习了结构型模式的享元模式和代理模式.本篇则来学习下行为型模式的两个模式, 责任链模式(Chain of Responsibility Pattern)和命令模式(Command ...

  6. Java设计模式之责任链模式、职责链模式

    本文继续介绍23种设计模式系列之职责链模式.   什么是链 1.链是一系列节点的集合. 2..链的各节点可灵活拆分再重组.   职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间 ...

  7. Java设计模式应用——责任链模式

    生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的. 在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作.如 ...

  8. java设计模式之责任链模式以及在java中作用

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

  9. 击鼓传花联想到了Java设计模式:责任链模式

    目录 应用场景 简单示例 责任链模式 定义 意图 主要解决问题 何时使用 优缺点 击鼓传花的故事 应用场景 http web请求处理,请求过来后将经过转码.解析.参数封装.鉴权等一系列的处理(责任), ...

  10. Java设计模式---ChainOfResponsibility责任链模式

    参考于 : 大话设计模式 马士兵设计模式视频 代码参考于马士兵设计模式视频 写在开头:职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系 图来自大话设计模式,下面我的代 ...

随机推荐

  1. Android开发之Navigationdrawer导航抽屉功能的实现(源码分享)

    导航抽屉(navigationdrawer)是一个从屏幕左边滑入的面板,用于显示应用的主要导航项目.用户能够通过在屏幕左边缘滑入或者触摸操作栏的应用图标打开导航抽屉. 导航抽屉覆盖在内容之上,但不覆盖 ...

  2. 第一章 EL表达式常见用法

    el最常用的几种使用场景: 从配置文件中读取属性 缺失值情况下,配置默认值 el内部字符串使用String的方法 三目运算符 正则表达式 注入系统属性(system properties) 调用系统原 ...

  3. vue当前路由跳转初步研究

    一样闲话少说,直接上问题,如图: 也是消息面板,没想到一个小小的消息面板,碰到这么多坑,惆怅. 就是如果当前路由和跳转路由不一样时,正常跳转没有任何问题.但是如果一样时,就不会跳转了,用了很多方法,比 ...

  4. Android GUI之Window、WindowManager

    通过前几篇的文章(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#gui ),我们清楚了Activity实际上是将视图的创建和显示交给了Wi ...

  5. 比较windows phone 的回退事件与android的回退事件

    public void onBackPressed() { finish(); } 如果要做一个页面导航的功能的话,就我而言,认为,windows phone开发比android更加人性化,更加傻瓜化 ...

  6. 安装Oracle之后解决掉的问题分享

    TNS-03505: 无法解析名称                                                            在测试tnsping的时候始终显示这么个问题. ...

  7. Inside GDALAllRegister之二: 自动加载驱动

    代码    GetGDALDriverManager()->AutoLoadDrivers(); 包含了两部分: 首先获得GDALDriverManager的singleton对象的指针,这点之 ...

  8. XML基础以及用DOM4j读取数据

    都知道,HTML被设计用来显示数据,XML被设计用来保存.数据传输.而我们平时经经常使用的无非是保存数据.读取数据.所以这里主要介绍XML相关基础内容.以及用DOM4j来存取XML的数据. 以下简单介 ...

  9. 创建并发布node.js module

      创建node.js module. 创建一个文件夹,用来存放module. Cd到新创建的文件夹,运行npm init,会提示输入package的信息. 可以按照这个视频的来输入.Test com ...

  10. 下载RAD

    1.登录https://w3-103.ibm.com/software/xl/download/ticket.do 2.输入Intranet ID和pswd,然后选I Agree. 3.然后点Sear ...