一、责任链模式概述

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

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

  定义责任链

    (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. HDU 3923 Invoker(polya定理+乘法逆元(扩展欧几里德+费马小定理))

    Invoker Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 122768/62768K (Java/Other) Total Subm ...

  2. LeetCode OJ:Convert Sorted List to Binary Search Tree(将排序好的链表转换成二叉搜索树)

    Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...

  3. 块级元素display:inline-block 在IE6 IE7无效

    ie6,ie7中,对块级元素设置display:inline-block,无效. 所以要先设置为inline,再触发haslayout .div1{ /*重点代码开始*/ display: inlin ...

  4. jQuery 滑动选项卡jQuery tabslet

    Tabslet   Yet another jQuery plugin for tabs, lightweight, easy to use and with some extra features ...

  5. jauery-layer弹出框的使用

    一布局: <div id="detailLayer"> <div class="box-header"> <div class=& ...

  6. oracle对三个列求sum

    oracle数据库对test_table表的三个列count1,count2,count3求sum的两种sql,做个记录 第一种 select sum (case when count1 is not ...

  7. 解决apt-get安装中的E: Sub-process /usr/bin/dpkg returned an error code (1)问题

    在用apt-get安装软件包的时候遇到E: Sub-process /usr/bin/dpkg returned an error code (1)问题,解决方法如下: cd /var/lib/dpk ...

  8. .NET 方法回调

    使用 AsyncCallback 委托在一个单独的线程中处理异步操作的结果. AsyncCallback 委托表示在异步操作完成时调用的回调方法. 回调方法采用 IAsyncResult 参数,该参数 ...

  9. MySQL 存储过程,游标,临时表创建

    -- -------------------------------------------------------------------------------- -- Routine DDL - ...

  10. jQuery插件实现表格隔行换色且感应鼠标高亮行变色

    实现表格隔行换色,且感应鼠标行变色的方法有很多,在本文将为大家介绍的是使用jQuery插件来实现,具体如下 看代码: : css代码: