责任链模式简介
责任链(Chain of Responsibility)设计模式 :
责任链模式是对象的行为模式。使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系。
一个简单的案例
蜀汉公司的请假审批过程
- 如果请假小于2天,由主任 张飞 审批
- 如果请假天数大于2天 小于 7 天,则由经理 关二哥 审批
- 如果请假天数大于等于7天小于20天 ,则由董事长 刘老大审批
- 如果大于等于20天 坚决拒绝
诚然,我们第一反应,这可以使用 if else 语句完美解决但是一旦业务复杂起来,那么使用 if else 难免造成程序的混乱。而且,一旦需求有变,那么就必须将源代码进行大量修改。使用 责任链设计模式 则可以较好的解决这一问题,即使是需求有变,我们也可以通过反射机制,通过读取配置文件的方式,进行修改。而不需要修改源代码。
它使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
下面开始quickstart
1.首先定义一个request请求
request请求模型是一个javabean 有员工姓名请假天数和请假原因
public class Request {
/**
* 员工姓名
*/
private String empName;
/**
* 请假天数
*/
private int dayNum;
/**
* 请假原因
*/
private String reason;
public Request(String empName, int dayNum, String reason) {
super();
this.empName = empName;
this.dayNum = dayNum;
this.reason = reason;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public int getDayNum() {
return dayNum;
}
public void setDayNum(int dayNum) {
this.dayNum = dayNum;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
2.定义一个Handler 抽象类
public abstract class Handler {
protected String name;
protected Handler nextHandler;
/**
* 设置领导的姓名
* @param name
*/
public Handler(String name) {
super();
this.name = name;
}
/**
* 设置责任链表的后继
* @param nextHandler
*/
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 处理业务的方法
* @param request
*/
public abstract void handleRequest(Request request);
}
3.根据handler 创建 处理 的领导人
/**
* 主任
* @author guxiang
* @date 创建时间:2017年2月6日 上午12:27:30
* @version 1.0
*/
public class Director extends Handler {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if (request.getDayNum()<2) {
System.out.println("员工"+request.getEmpName()+"由于"+request.getReason()+"请假"+request.getDayNum()+"天");
System.out.println("主任:"+this.name+"同意!");
}else {
if (this.nextHandler!=null) {
this.nextHandler.handleRequest(request);
}
}
}
}
/**
* 经理
* @author guxiang
* @date 创建时间:2017年2月6日 上午12:26:08
* @version 1.0
*/
public class Manger extends Handler {
public Manger(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if (request.getDayNum()<7) {
System.out.println("员工"+request.getEmpName()+"由于"+request.getReason()+"请假"+request.getDayNum()+"天");
System.out.println("经理:"+this.name+"同意!");
}else {
if (this.nextHandler!=null) {
this.nextHandler.handleRequest(request);
}
}
}
}
package chainOfResp;
/**
* 董事长
* @author guxiang
* @date 创建时间:2017年2月6日 上午12:29:34
* @version 1.0
*/
public class Chairman extends Handler {
public Chairman(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if (request.getDayNum()<20) {
System.out.println("员工"+request.getEmpName()+"由于"+request.getReason()+"请假"+request.getDayNum()+"天");
System.out.println("董事长:"+this.name+"同意!");
}else {
System.out.println("坚决不同意!");
}
}
}
3.我们定义一个client 来测试
public class Client {
public static void main(String[] args) {
Handler director = new Director("张三");
Handler manger = new Manger("关二哥");
Handler chairman = new Chairman("刘老大");
//设置关系
director.setNextHandler(manger);
manger.setNextHandler(chairman);
Request request1 = new Request("甲", 1, "回家陪老婆");
director.handleRequest(request1);
/*
* 结果: 员工甲由于回家陪老婆请假1天
主任:张三同意!
*/
Request request2 = new Request("乙", 12, "回家老家看亲戚");
director.handleRequest(request2);
/*
* 结果: 员工乙由于回家老家看亲戚请假12天
董事长:刘老大同意!
*/
Request request3 = new Request("乙", 21, "母亲生病了");
director.handleRequest(request3);
/*
* 结果: 坚决不同意!
*/
}
}
责任链设计模式的应用场景
1. java中 我们常用的 try catch catch catch 就是一种责任链 一个try可以对应多个catch
2. 在javaweb中 filter 就是非常典型的责任链设计模式
3. 在struts2中 拦截器也是非常经典的责任链设计模式
等等。。。
2,3两种 就是不修改源代码的责任链设计模式