一、责任链模式概述

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

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

  定义责任链

    (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. 二、DBMS_JOB(用于安排和管理作业队列)

    1.概述 作用:用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务注意:当使用DBMS_LOB管理作业时,必须确保设置了初始化参数job_queue_processes( ...

  2. TPCC-MySQL(转自imysql.com)

    [Tpcc-mysql] Tpcc-mysql是percona基于tpcc衍生出来的产品,专用于mysql基准测试,其源码放在bazaar(Bazaar是一个分布式的版本控制系统,采用 GPL 许可协 ...

  3. Unix系统中system函数的返回值

    网上关于system函数的返回值说明很多很详细但却不直观,这里搬出apue 3rd Editon中实现system函数的代码来说明其返回值. #include <sys/wait.h> # ...

  4. Linux(CentOS7)下发送邮件(使用Gmail作为发件服务器)

    参考下述文章的思路,补充了在Gmail上的相关设置 https://gist.github.com/ilkereroglu/aa6c868153d1c5d57cd8 1.安装mailx yum ins ...

  5. Visual Studio编译与调用DLL方法

    参考自博客:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 用visual studio 2013新建win32 appli ...

  6. 11.Linux启动过程详解

    目录: 本文转载自:http://blog.csdn.net/miss_acha/article/details/50004717 经过对Linux系统有了一定了解和熟悉后,想对其更深层次的东西做进一 ...

  7. iOS数组的去重,判空,删除元素,删除重复元素 model排序 等

    一: 去重 有时需要将NSArray中去除重复的元素,而存在NSArray中的元素不一定都是NSString类型.今天想了想,加上朋友的帮助,想到两种解决办法,先分述如下. 1.利用NSDiction ...

  8. (转) 从windows XP到10的微软官方操作系统虚拟机镜像,即下即用,不用安装

    原文地址: https://blog.csdn.net/tool321_com/article/details/50707512 最近在帮朋友安装虚拟机,遇到了这么一个东西,感觉比较不错,分享如下: ...

  9. Makefile总结

    1.Makefile由目标(Target).依赖关系(Dependency).命令(Command)组成. (1)目标:可定义多个目标,默认指定第一个,make时可指定其中一个. (2)依赖关系:在同 ...

  10. linux自学(九)之开始centos学习,安装数据库MariaDB

    上一篇:linux自学(八)之开始centos学习,安装tomcat 数据库我们不安装mysql,我网上看了好多资料发现mysql安装比较麻烦,我们这里安装同一个父亲的产品MariaDB.驱动,端口等 ...