设计模式之(十四)责任链模式(Chain of Responsibility)
在业务场景中,有很多是需要审批的。审核方式还可能常常发生变化,而责任链模式就是为了解决这种场景的情况的。
责任链模式定义:十多个对象都有机会处理请求,从而避免发送者和接受者之间的耦合关系。讲这些对象连成一条链,并沿着这条链传送这个请求,直到有一个对象处理他为止。
责任链模式的思想就是把处理请求的处理都拆开,一个处理逻辑封装成一个小颗粒类,在需要使用的时候就可以按照业务需要排序起来处理,就像一个链条。但是在这个过程中可能走完了也没有得到处理,这就需要给出一个默认的处理,而给出处理结果。接下来看看此模式的类图:
从这个图里可以看出来,这个模式和递归算法很大关系,接下来通过一个例子来加深对此模式的理解。
1 /*** 2 * 处理类的抽象类 3 * @author pwq 4 */ 5 public abstract class Handle { 6 protected Handle successor = null; 7 8 public void setSuccessor(Handle successor) { 9 this.successor = successor; 10 } 11 12 public abstract String handleFeeRequest(String user,double fee); 13 14 } 15 16 /*** 17 * 其中一个处理逻辑类 18 * @author pwq 19 */ 20 public class ProjectManager extends Handle { 21 22 @Override 23 public String handleFeeRequest(String user, double fee) { 24 // TODO Auto-generated method stub 25 String str ="" ; 26 if(fee < 500){ 27 if("小李".equals(user)){ 28 str = "项目经理同意"+user+"申请的聚餐费用 "+ fee +" 元"; 29 } 30 else{ 31 str = "项目经理不同意"+user+"申请的聚餐费用 "+ fee +" 元"; 32 } 33 } 34 else{ 35 if(successor != null) 36 str = successor.handleFeeRequest(user, fee); 37 } 38 return str; 39 } 40 }
1 /*** 2 * 处理逻辑类 3 * @author pwq 4 * 5 */ 6 public class DeptManager extends Handle { 7 8 @Override 9 public String handleFeeRequest(String user, double fee) { 10 // TODO Auto-generated method stub 11 String str ="" ; 12 if(fee < 1000){ 13 if("小李".equals(user)){ 14 str = "部门经理同意"+user+"申请的聚餐费用 "+ fee +" 元"; 15 } 16 else{ 17 str = "部门经理不同意"+user+"申请的聚餐费用 "+ fee +" 元"; 18 } 19 } 20 else{ 21 if(successor != null) 22 str = successor.handleFeeRequest(user, fee); 23 } 24 return str; 25 } 26 }
1 public class GeneralManager extends Handle { 2 3 @Override 4 public String handleFeeRequest(String user, double fee) { 5 // TODO Auto-generated method stub 6 String str ="" ; 7 if(fee >= 1000){ 8 if("小李".equals(user)){ 9 str = "总经理同意"+user+"申请的聚餐费用 "+ fee +" 元"; 10 } 11 else{ 12 str = "总经理不同意"+user+"申请的聚餐费用 "+ fee +" 元"; 13 } 14 } 15 else{ 16 if(successor != null) 17 str = successor.handleFeeRequest(user, fee); 18 } 19 return str; 20 } 21 }
1 public class Client { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 Handle h1=new ProjectManager(); 6 Handle h2 = new DeptManager(); 7 Handle h3 = new GeneralManager(); 8 9 h1.setSuccessor(h2); 10 h2.setSuccessor(h3); 11 12 String str = h1.handleFeeRequest("万小弟", 600); 13 System.out.println(str); 14 String str2 = h1.handleFeeRequest("彭大哥", 1800); 15 System.out.println(str2); 16 String str3 = h1.handleFeeRequest("小李", 400); 17 System.out.println(str3); 18 } 19 } 20 21 22 /*****************************************************/ 23 24 部门经理不同意万小弟申请的聚餐费用 600.0 元 25 总经理不同意彭大哥申请的聚餐费用 1800.0 元 26 项目经理同意小李申请的聚餐费用 400.0 元
通过这个例子分析处理类的写法,如果从抽象类来看的话,就是递归算法来达到让每个逻辑都有机会处理请求的。要类里面要定义下个环节处理的逻辑类变量,在使用的时候通过这个设置来组成处理的链。
例子展示的是责任链,也就是典型的审批的流程这样场景。还有另外一种用法,就是功能链,功能链就是把从多功能拆分到单一功能类中,可以根据需要来调用,相对来说更灵活,也便于复用。
责任链的有点和缺点
优点就是:
1、把复杂功能拆分处理,让每个类只是负责一个处理逻辑。复用性更好,组合更加灵活。
2、请求和处理类分开,实现低耦合,更加利于扩展。
缺点:小颗粒类大幅膨胀。
模式的本质
分离职责,动态组合