责任链模式的定义:
责任链模式就是使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。责任链模式重点是在链上,链上的节点都有可能处理请求,前提是必须是符合处理该节点处理条件,如果不符合将继续查找下一个节点,而处理功能通常会采用递归的形式。
责任链模式的实现:
需求:完成公司请假模块的开发,公司现在请假流程还是比较简单的,只需要向自己的上级领导请示通过就可以了,公司一个有组员,组长,总监,总经理四个职务
设计思路:
角色:定义一个员工接口Iemployees,员工根据等级划分,请假功能:Ihandler抽象处理流程类,每个职级只需要向自己的上级提交申请。请假流程方法vacate需要判断请假员工的等级是否在自己的处理范围之内,如果没有,则交由自己的下一级处理。
类图:
代码实现:
package com.chain;
/**
* 请假流程
*/
public abstract class Ihandler {
//下一个处理者
private Ihandler nextIhandler;
//处理等级
protected String disposLlevel;
//请假流程
public final void vacate(Iemployees employees){
if(getDisposLevel().equals(employees.getLevel())){
echo();
}else{
if(nextIhandler!=null){
nextIhandler.vacate(employees);
}else {
System.out.println("无符合条件的人员");
}
}
}
//设置下一个处理者
protected void setNext(Ihandler ihandler){
this.nextIhandler = ihandler;
}
//处理结果
protected abstract void echo();
//
//获得自己职级
protected abstract String getDisposLevel();
}
package com.chain;
/**责任链模式
* 总监
*/
public class DirectorHandler extends Ihandler{
//可以批准的等级
public static final String DISPOSLEVEL = "1";
@Override
protected void echo() {
System.out.println("总监批准了");
}
@Override
protected String getDisposLevel() {
return DISPOSLEVEL;
}
}
package com.chain;
public class LeaderIhandler extends Ihandler{
//可以批准的等级
public static final String DISPOSLEVEL = "0";
@Override
protected void echo() {
System.out.println("组长批准了");
}
@Override
protected String getDisposLevel() {
return DISPOSLEVEL;
}
}
package com.chain;
/**
* 责任链模式
* 经理
*/
public class ManagerHandler extends Ihandler {
public static final String DISPOSLEVEL = "2";
@Override
protected void echo() {
System.out.println("总经理批准了");
}
@Override
protected String getDisposLevel() {
return DISPOSLEVEL;
}
}
package com.chain;
/**
* 责任链模式
* 员工接口
*/
public interface Iemployees {
public String getLevel();
}
package com.chain;
/**
* 责任链模式
* 员工类
*/
public class Employees implements Iemployees{
/**
* 职位等级
* 0-普通员工
* 1-组长
* 2-总监
* 3-经理
*/
private String level;
public Employees(String level){
this.level = level;
}
@Override
public String getLevel() {
return level;
}
}
package com.chain;
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
//设置级别关系
DirectorHandler directorHandler = new DirectorHandler();
LeaderIhandler leaderIhandler = new LeaderIhandler();
ManagerHandler managerHandler = new ManagerHandler();
leaderIhandler.setNext(directorHandler);
directorHandler.setNext(managerHandler);
Employees xiaosan = new Employees("0");
System.out.println("组员小三想请假");
leaderIhandler.vacate(xiaosan);
System.out.println("组长小六想请假");
Employees xiaoliu = new Employees("1");
directorHandler.vacate(xiaoliu);
System.out.println("总监小九想请假");
Employees xiaojiu = new Employees("2");
managerHandler.vacate(xiaojiu);
System.out.println("总经理想请假");
Employees manager = new Employees("3");
managerHandler.vacate(manager);
}
}
//执行结果
组员小三想请假
组长批准了
组长小六想请假
总监批准了
总监小九想请假
总经理批准了
总经理想请假
无符合条件的人员
从代码中可以看出处理节点会先判断是否是自己的处理范围,如果不是会查看是否存在下一个节点递归调用继续处理请求。不过这个例子有点问题,由于已经明确了职级,所以并没有实际体现出链的传递性。(后续想到好的例子修改下)
责任链模式的优缺点:
责任链模式将请求和处理请求分开,请求只管请求并不清楚是谁处理请求,而处理者也无需知道请求的全面信息,只需要判断请求的类型才判断是否处理。请求者和处理者解耦提高了系统的灵活性和扩展性。
不过劣势也异常明显,请求的每次处理都需要链的头开始,所以链如果越长对性能的影响越明显,而且如果使用递归的化更需要注意,递归一定要有出口。同时可以给链设定一个阈值,保证链有一个固定长度。
参考《设计模式之禅》秦小波著