职责链模式
所谓职责链模式,其实在现实中非常常见,比如你要提出一个申请,首先可能通过你的组长,你的组长没有权力审批时会上报到经理,经理没有权力审批时上报到总监,总监没有没有权力审批时上报到总经理等等,以此类推直到有权力的管理者来审批。
这种场景我们可以用if-else判断分支来实现,不过记住大量的if-else判断分支并不是一个好的设计,此时我们可以采用“职责链模式”来解决。
首先不管领导是谁,他们都是管理者,那么我们抽象出一个管理者公共抽象类,如下图所示:
职责链模式中有很重要的一点就是,当该处理类没有权限不能处理此请求时需要将请求传递给下一个处理类,以此类推,直到有权限处理类处理该请求时即停止将请求传递给下一个处理类。所以我们画出职责链模式的UML类结构图。
同样我们用代码来实现,定义一个Handler抽象类,其中有一个具体方法是设置处理类的后继者,这样才能实现当一个具体的处理类不能处理该请求时将请求转发给它的后继者,还有一个抽象方法是其各个派生类实现自己的处理方法。
1 package day_9_chain; 2 3 /** 4 * 抽象处理公共类 5 * @author 余林丰 6 * 7 * 2016年10月10日 8 */ 9 public abstract class Handler { 10 protected Handler handler; 11 12 public void setNextHandler(Handler handler){ 13 this.handler = handler; 14 } 15 16 public abstract void request(int request); 17 }
接下来是3个具体的处理类。
1 package day_9_chain; 2 3 /** 4 * 具体处理类1 5 * @author 余林丰 6 * 7 * 2016年10月10日 8 */ 9 public class ConcreteHandler1 extends Handler { 10 11 /* (non-Javadoc) 12 * @see day_9_chain.Handler#request(int) 13 */ 14 @Override 15 public void request(int request) { 16 if (request >=0 && request <= 10){ 17 System.out.println("ConcreteHandler1处理请求:" + request); 18 } else if (handler != null){ 19 handler.request(request); 20 } 21 } 22 23 }
1 package day_9_chain; 2 3 /** 4 * 具体处理类2 5 * @author 余林丰 6 * 7 * 2016年10月10日 8 */ 9 public class ConcreteHandler2 extends Handler { 10 11 /* (non-Javadoc) 12 * @see day_9_chain.Handler#request(int) 13 */ 14 @Override 15 public void request(int request) { 16 if (request > 10 && request <= 20){ 17 System.out.println("ConcreteHandler2处理:" + request); 18 } else if (handler != null){ 19 handler.request(request); 20 } 21 } 22 23 }
1 package day_9_chain; 2 3 /** 4 * 具体处理类3 5 * @author 余林丰 6 * 7 * 2016年10月10日 8 */ 9 public class ConcreteHandler3 extends Handler { 10 11 /* (non-Javadoc) 12 * @see day_9_chain.Handler#request(int) 13 */ 14 @Override 15 public void request(int request) { 16 if (request > 20 && request <= 30){ 17 System.out.println("ConcreteHandler3处理:" + request); 18 } else if (handler != null){ 19 handler.request(request); 20 } 21 } 22 23 }
客户端测试代码。
1 package day_9_chain; 2 3 /** 4 * @author 余林丰 5 * 6 * 2016年10月10日 7 */ 8 public class Client { 9 10 11 public static void main(String[] args) { 12 ConcreteHandler1 concreteHandler1 = new ConcreteHandler1(); 13 ConcreteHandler2 concreteHandler2 = new ConcreteHandler2(); 14 ConcreteHandler3 concreteHandler3 = new ConcreteHandler3(); 15 16 concreteHandler1.setNextHandler(concreteHandler2); 17 concreteHandler2.setNextHandler(concreteHandler3); 18 19 concreteHandler1.request(25); 20 21 } 22 23 }
我们可以看到职责链的好处在于:当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。它们仅需保持一个指向其后继者的引用,而且并不需要保持它后面所有后继者的引用。和这个职责链模式类似的还有一个东西叫做“链处理”,需要导入一个叫做commons-chain的jar包,这个也很实用,它用来描述一个顺序处理的过程,有兴趣可以看一看。
不积跬步,无以至千里;不积小流,无以成江海。