生活中经常会出现这样的问题:在企业中员工请假问题。一个员需要请一周假,如果把请假申请单看成一个对象,那么它需要由组长(假期少于1天可决定)、车间主任(假期少于两天可决定)、经理等多个角色的审批。
这样用一系列类(classes)试图去处理一个请求request。及请求生成后,A类先处理,如果没有处理就传到B类处理,如果没有处理再传到C类处理,这样像一条链一样传递下去。
责任链设计模式的类图:
责任链模式编写员工请假审批功能类:
1.请求类Request
/*
* 请求类
*/
public class Request {
int day;//请假天数
public Request(int day) {
this.day = day;
}
}
2.抽象处理者类Handler
/*
* 抽象处理者类
*/
public abstract class Handler {
private Handler next;//后继处理者变量
public void setNext(Handler next) {
this.next = next;
}
public Handler getNext() {
return next;
}
public abstract boolean handle(Request req); //定义抽象请求方法,子类要重写
}
3.三个具体处理类
/*
* 具体处理类:组长
*/
public class ZuZhang extends Handler {
static int limit = 1;
public boolean handle(Request req) {
if (req.day <= limit) {
System.out.println("ZuZhang agrees the requests");
return true;
}
return getNext().handle(req);
}
}
/*
* 具体处理类:主任
*/
public class ZhuRen extends Handler {
static int limit = 2;
public boolean handle(Request req) {
if (req.day <= limit) {
System.out.println("ZhuRen agrees the requests");
return true;
}
return getNext().handle(req);
}
}
/*
* 具体处理类:经理
*/
public class JingLi extends Handler {
public boolean handle(Request req) {
System.out.println("ZhuRen agrees the requests");
return true;
}
}
4.生成责任链前后顺序关系类
public class MyChain {
private Handler one = new ZuZhang();
private Handler two = new ZhuRen();
private Handler three = new JingLi();
public void creatChain() {
one.setNext(two);
two.setNext(three);
}
public void handle(Request req) {
one.handle(req);
}
}
5.测试类
public class Test {
public static void main(String[] args) {
Request req = new Request(2);
MyChain mc = new MyChain();
mc.creatChain(); //创建责任链
mc.handle(req); //将请求放入链中
}
}
上面那样写的话,当需求发生变化,链中需要增加或减少节点时,得修改MyChain类。但我们想尽量少的修改代码?那么你是否想到了“配置文件+反射”的做法呢,那就对了。
1.myconfig.txt
//键固定为chain,值为该链上的所有节点类,必须是全包路径
chain=com.chainofresponsibility.ZuZhang,com.chainofresponsibility.ZhuRen,
com.chainofresponsibility.JingLi
2.MyChain2
package com.chainofresponsibility;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class MyChain2 {
private Handler handle[];
public void creatChain() {
try {
String path = this.getClass().getResource("/").getPath();
// 读配置文件
FileInputStream in = new FileInputStream(path + "chainofresponsibility/myconfig.txt");
Properties p = new Properties();// 获取责任链总串
p.load(in);
String s = p.getProperty("chain");
String unit[] = s.split(",");
for (int i = 0; i < unit.length; i++) {
// 通过反射加载各责任链对象
handle[i] = (Handler) Class.forName(unit[i]).newInstance();
}
for (int i = 0; i < unit.length; i++) {
handle[i].setNext(handle[i + 1]);// 设置节点前后关系
}
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void handle(Request req) {
handle[0].handle(req);
}
}
一个对象在一条链上被多个拦截器拦截处理(拦截器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景。