我向boss请假,如果只请一天,只要项目经理签字就行了,如果超过5天,项目经理签完字以后还要公司老大签字,如果超过10天,那就要集团老总签字了。反映在程序上,就是责任链模式。
责任链模式的定义为:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
就像第一段的场景,我只要把申请在oa上提交给项目经理就行了,最后谁签字谁处理我不关心,我只关心结果。代码如下:
首先,定义一个枚举,规定了各个责任节点上能够处理的等级:
package InvolvedMode.Handler; /** * Level : 责任链模式中的处理等级 * @author xuejupo [email protected] * * create in 2015-12-28 下午2:39:15 */ public enum Level { //小领导 LEADER, //公司主管 Boss, //集团总裁 CHAIRMAN; }
抽象责任类:
/** * Handler:责任链模式中的抽象责任类 * @author xuejupo [email protected] * create in 2015-12-28 下午2:43:48 * */ abstract class Handler{ //每个责任节点应该有个名字 protected String name; //责任链的下一个节点 protected Handler nextHandler; //责任者负责的level protected Level level; /** * handleRequest: 责任链的主要方法,负责处理任务---处理或者交给下一个责任者 * @param request * void 返回类型 */ public abstract void handleRequest(Request request); /** * * getNextName: 获取下一个责任链的名字 * @return * String 返回类型 */ public abstract String getNextName(); }
责任链中的具体责任类,负责干活的:
/** * ConHandler:责任链模式中的责任类 负责处理业务逻辑 * @author xuejupo [email protected] * create in 2015-12-28 下午3:34:11 * */ class ConHandler extends Handler{ public ConHandler(Level level,Handler nextHandler,String name){ this.level = level; this.name = name; this.nextHandler = nextHandler; } @Override public void handleRequest(Request request) { // TODO Auto-generated method stub //处理我的责任: this.handMyRequest(request); //如果处理完了,则完成: if(request.getLevels().size() == 0){ System.out.println("处理完成!"); }else{ //交给我的下一个责任点: System.out.println("交给:\t"+this.getNextName()); this.nextHandler.handleRequest(request); } } /** * handMyRequest: 处理我的责任 * @param request * void 返回类型 */ private void handMyRequest(Request request){ Iterator<Level> i = request.getLevels().iterator(); while(i.hasNext()){ Level level = i.next(); if(level.equals(this.level)){ System.out.println("我是:"+this.name+"\t我在处理"); i.remove(); } } } @Override public String getNextName() { // TODO Auto-generated method stub return this.nextHandler.name; } }
责任链的请求类:
/** * Request: 责任链的请求发出者(简单的一个类,就不抽象了) * @author xuejupo [email protected] * create in 2015-12-28 下午2:48:43 * */ class Request{ //请求者的请求链 private List<Level> levels = new ArrayList<Level>(); //请求者增加请求 public void addLevel(Level level){ this.levels.add(level); } //获得请求者的请求链 public List<Level> getLevels(){ return this.levels; } }
测试代码:
/** * HandlerTest : 责任链模式 * @author xuejupo [email protected] * create in 2015-12-28 下午2:39:06 */ public class HandlerTest { /** * main: * @param args * void 返回类型 */ public static void main(String[] args) { // TODO Auto-generated method stub //定义一个请求 Request request = new Request(); //需要领导签字 request.addLevel(Level.LEADER); //需要boss签字 request.addLevel(Level.Boss); //需要集团总裁签字 request.addLevel(Level.CHAIRMAN); //定义具体的责任对象: //1.集团总裁 Handler chairman = new ConHandler(Level.CHAIRMAN,null,"集团老大"); //公司主管 Handler boss = new ConHandler(Level.Boss,chairman,"公司老大"); //项目经理 Handler leder = new ConHandler(Level.LEADER,boss,"直接领导"); //直接领导开始处理请求 leder.handleRequest(request); } }
结果:
我是:直接领导 我在处理 交给: 公司老大 我是:公司老大 我在处理 交给: 集团老大 我是:集团老大 我在处理 处理完成!
仔细看责任链模式的定义可以发现,其实上面代码不算一个纯粹的责任链模式。纯粹的责任链模式应该是像java的类加载器classloder一样,当前责任节点或者完成加载,或者交给下一个责任节点,不会出现当前节点加载一部分的情况。但是上面代码不能说他不是责任链模式吧。。。 这也算责任链的一种。写代码,真不用死扣定义,完全按照定义写代码,最关键的是写出高效可扩展的代码,其他都是浮云。
责任链可扩展性很强,比如上面的代码,我请假只跟项目经理打招呼,项目经理怎么处理我不知道,所以如果需要修改项目经理或者其他节点的处理逻辑,不用通知“我”这个类,易扩展。
还有个好处就是安全。责任链可以让我们隐藏底层(公司老大和集团老大),只提供业务层即可(项目经理)