一、责任链模式概述

  将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求。

  如果能则处理,否则传递给链上的下一个对象去处理。

  定义责任链

    (1)通过链表的方式实现职责链

    (2)通过非链表的方式实现职责链

        通过集合、数组生成职责链更加实用!实际上,很多项目中,每个具体的Handler并不是由开发团队定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义责任链(COR)就很困难!

二、责任链模式场景

  (1)公司里面,请假条审批过程:

      ① 如果请假天数小于3天,主任审批

      ② 如果请假天数大于等于3天,小于10天,经理审批

      ③ 如果请假天数大于等于10天,小于30天,总经理审批

      ④ 如果请假天数大于等于30天,提示拒绝

  (2)添加新的处理对象:

      可以在流程中增加新的“副总经理”角色,审批大于等于10天,小于20天的情况。

      ① 如果请假天数小于3天,主任审批

      ② 如果请假天数大于等于3天,小于10天,经理审批

      ③【增加】如果请假天数大于等于10天,小于20天,副总经理审批

      ④ 如果请假天数大于等于20天,小于30天,总经理审批

      ⑤ 如果请假天数大于等于30天,提示拒绝

三、使用责任链模式模拟公司请假流程

 /**
* 封装请假的基本信息
* @author CL
*
*/
public class LeaveRequest {
/**
* 员工姓名
*/
private String empName;
/**
* 请假天数
*/
private int leaveDays;
/**
* 请假事由
*/
private String reason; public LeaveRequest() {
} public LeaveRequest(String empName, int leaveDays, String reason) {
this.empName = empName;
this.leaveDays = leaveDays;
this.reason = reason;
} public String getEmpName() {
return empName;
} public void setEmpName(String empName) {
this.empName = empName;
} public int getLeaveDays() {
return leaveDays;
} public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
} public String getReason() {
return reason;
} public void setReason(String reason) {
this.reason = reason;
} }
 /**
* 抽象类(领导)
* @author CL
*
*/
public abstract class Leader {
protected String name;
/**
* 责任链上的后继对象
*/
protected Leader nextLeader; public Leader(String name) {
this.name = name;
} /**
* 设定责任链上的后即对象
* @param nextLeader
*/
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
} /**
* 处理请假请求的核心业务方法
* @param leaveRequest
*/
public abstract void handlerRequest(LeaveRequest leaveRequest); }
 /**
* 主任
* @author CL
*
*/
public class Director extends Leader { public Director(String name) {
super(name);
} @Override
public void handlerRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() < 3) {
System.out.println("员工:"+leaveRequest.getEmpName()+",请假:"
+leaveRequest.getLeaveDays()+"天,理由:"+leaveRequest.getReason());
System.out.println("主任:"+this.name+",审批通过!");
} else { //责任链上的后继对象处理
if (this.nextLeader != null) {
this.nextLeader.handlerRequest(leaveRequest);
}
}
} }
 /**
* 经理
* @author CL
*
*/
public class Manager extends Leader { public Manager(String name) {
super(name);
} @Override
public void handlerRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() < 10) {
System.out.println("员工:"+leaveRequest.getEmpName()+",请假:"
+leaveRequest.getLeaveDays()+"天,理由:"+leaveRequest.getReason());
System.out.println("经理:"+this.name+",审批通过!");
} else { //责任链上的后继对象处理
if (this.nextLeader != null) {
this.nextLeader.handlerRequest(leaveRequest);
}
}
} }
 /**
* 副总经理
* @author CL
*
*/
public class ViceGeneraManager extends Leader { public ViceGeneraManager(String name) {
super(name);
} @Override
public void handlerRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() < 20) {
System.out.println("员工:"+leaveRequest.getEmpName()+",请假:"
+leaveRequest.getLeaveDays()+"天,理由:"+leaveRequest.getReason());
System.out.println("副总经理:"+this.name+",审批通过!");
} else { //责任链上的后继对象处理
if (this.nextLeader != null) {
this.nextLeader.handlerRequest(leaveRequest);
}
}
} }
 /**
* 总经理
* @author CL
*
*/
public class GeneraManager extends Leader { public GeneraManager(String name) {
super(name);
} @Override
public void handlerRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getLeaveDays() < 30) {
System.out.println("总经理:"+leaveRequest.getEmpName()+",请假:"
+leaveRequest.getLeaveDays()+"天,理由:"+leaveRequest.getReason());
System.out.println("主任:"+this.name+",审批通过!");
} else { //无责任链上的后继对象
System.out.println("员工:"+leaveRequest.getEmpName()+",请假天数:"
+leaveRequest.getLeaveDays()+"天,超过30天,不予请假!");
}
} }

  测试:

 /**
* 测试责任链模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
Leader a = new Director("张主任");
Leader b = new Manager("李经理");
Leader c = new ViceGeneraManager("王副总经理");
Leader d = new GeneraManager("赵总经理"); //构建责任链
a.setNextLeader(b);
b.setNextLeader(c);
c.setNextLeader(d); //请假
LeaveRequest req1 = new LeaveRequest("Tom", 2, "生病");
LeaveRequest req2 = new LeaveRequest("Jame", 15, "回家");
LeaveRequest req3 = new LeaveRequest("Rose", 25, "调休");
LeaveRequest req4 = new LeaveRequest("Jack", 35, "闹着玩"); //审批
a.handlerRequest(req1);
a.handlerRequest(req2);
a.handlerRequest(req3);
a.handlerRequest(req4);
}
}

  控制台输出:

员工:Tom,请假:2天,理由:生病
主任:张主任,审批通过!
员工:Jame,请假:15天,理由:回家
副总经理:王副总经理,审批通过!
总经理:Rose,请假:25天,理由:调休
主任:赵总经理,审批通过!
员工:Jack,请假天数:35天,超过30天,不予请假!

四、责任链模式常见开发应用场景

  (1)Java 中,异常处理机制就是一种责任链模式。一个 try 可以对应多个 catch,当第一个 catch 不匹配类型,则自动跳到第二个 catch;

  (2)JavaScript 语言中,事件的冒泡和捕获机制(Java 语言中事件的处理采用观察者模式);

  (3)Servlet 开发中,过滤器的链式处理;

  (4)Struts2 中,拦截器的调用也是典型的责任链模式;

  (5)…………

GOF23设计模式之责任链模式(chain of responsibility)的更多相关文章

  1. 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)

    原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...

  2. 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...

  3. [设计模式] 13 责任链模式 Chain of Responsibility

    转    http://blog.csdn.net/wuzhekai1985   http://www.jellythink.com/archives/878 向项目经理提交了休假申请,我的项目经理向 ...

  4. 设计模式 笔记 责任链模式 chain of responsibility

    //---------------------------15/04/25---------------------------- //Chain of responsibility 责任链----- ...

  5. 责任链模式-Chain of Responsibility(Java实现), 例2

    责任链模式-Chain of Responsibility 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 咱们在 ...

  6. 责任链模式-Chain of Responsibility(Java实现), 例1

    责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...

  7. 《JAVA设计模式》之责任链模式(Chain of Responsibility)

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

  8. 责任链模式/chain of responsibility/行为型模式

    职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...

  9. 【GOF23设计模式】责任链模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 package com.test.chainO ...

随机推荐

  1. flask中过滤器的使用

    过滤器 过滤器的本质就是函数.有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化.运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器. 使用方 ...

  2. SQL SERVER - set statistics time on的理解

    一.set statistics time on的作用 显示分析.编译和执行各语句所需的毫秒数. 二.语法 SET STATISTICS TIME { ON | OFF } 注释 1.当 SET ST ...

  3. 创建python3.6的虚拟开发环境virtualenv

    为了保证各个项目环境和插件的相对独立,使用virtualenv作为python的虚拟运行环境,这样在项目维护方面,减少在依赖包上所花费的时间. 1.安装 virtualenv虚拟环境插件 pip in ...

  4. python应用中的小知识点

    1.with有什么作用 with的作用是自动管理上下文打开关闭文件的时候,可以用with,文件对象不再使用的时候,会自动给我们关闭,不需手动关闭了数据库连接的时候, 2.没有import的模块怎么快速 ...

  5. 在FP与DDD的道路上越走越远

    托辞 最近一口气读了若干本FP方面的书,可人是越来越懒了,要整理个什么东西却也没有那个精力,所以简单扔几张图,算是给自己一个提醒吧. 在此期间,我用并不纯熟的Scala和Groovy练了一把手.虽然只 ...

  6. apt-get -f install

    http://zhidao.baidu.com/link?url=tZLEfm1Ycc1pWS67-95fXU596CtwA_1l2pPfzINUTxvOCvWdf3JZsWuZNxsxn0Jv6Om ...

  7. MySQL存储引擎(engine:处理表的处理器)

    1.基本的操作命令: 1.查看所有存储引擎 show engines: 2.查看已有表的存储引擎: show create table 表名: 3.创建表指定的存储引擎 create table 表名 ...

  8. ubuntu安装lua5.3.2

    lua5.3要自主编译安装 1.获取源:weget http://www.lua.org/ftp/lua-5.3.2.tar.gz 2.解压:tar -zxf lua-5.3.2.tar.gz 3.编 ...

  9. ssm框架实现图片上传显示并保存地址到数据库

    本案例是通过springmvc+spring+mybatis框架以商品上传为例,实现的图片上传功能,并把图片的地址保存到数据库并在前台显示上传的图片. 本项目是使用maven搭建的项目,首先看下项目结 ...

  10. bzoj 4447 小凸解密码

    bzoj 4447 小凸解密码 先将原始状态的 \(B\) 处理出来,可以发现,若不修改,则每次指定的起始位置不同,对这个环 \(B\) 带来的影响只有 \(B_0\) 不同,即每次 \(B_0=A_ ...