一、责任链模式概述

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

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

  定义责任链

    (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. SC用法

    转自:(http://blog.163.com/yf_handsome/blog/static/20238174200802495124164/) SC使用这样的语法: 1. SC [Serverna ...

  2. rsync的服务端和客户端搭建

    首先要看看有没有rsync,没有就按装一个rsync 1配置文件 然后创建rsyncd.conf文件,并添加如下内容(文件默认不存在) [root@chensiqi2 backup]# cat /et ...

  3. *SCM-MANAGERtomcat寄宿使用

    采用的部署方式 TomCat 一个端口下部署多个 Application供不同部门使用 初始部署详参见 SCM-MANAGER 博文 日常使用添加部门操作步骤 从“D:\tomcat\webapps” ...

  4. python爬虫之性能相关

    性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...

  5. canvas 画布 文字描边

    总结一下,canvas 画布 文字描边的2种方法以及其不同的视觉效果: 效果图: 具体代码: <canvas id="canvas" width="800" ...

  6. iOS 可能用到的三方框架

    1.MWPhotoBrowser 第三方图片浏览器 https://github.com/mwaterfall/MWPhotoBrowser 2.SlackTextViewController  强大 ...

  7. Xcode Server (Xcode9)搭建CI

    Xcode 9将Xcode Server集成进来了,这是Xcode一个新特性,不用去单独下载server了,server可以用来做CI.自动化Test等等.这里主要介绍搭建CI,相当简单 打开开关,新 ...

  8. Apache .htaccess文件

    今天在将ThinkPHP的URL模式由普通模式(URL_MODE=1)http://localhost/mythinkphp/index.php/Index/user/id/1.html改为重写模式 ...

  9. python3之环境搭建以及基础语法

    早些时候,有一段时间吧,为了想免费下载网易云的收费音乐,也是翻了下python的教程的,语法方面没细致地去看,跟java.php.javascript这些都大同小异,也是面向对象的.那么,近期准备快速 ...

  10. [Scala]Scala学习笔记四 类

    1. 简单类与无参方法 class Person { var age = 0 // 必须初始化字段 def getAge() = age // 方法默认为公有的 } 备注 在Scala中,类并不声明为 ...