设计模式-责任链模式
责任链模式简介
定义:是一种对象行为模式,为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止
目标:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了
优点:
降低了对象之间的耦合度,使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息
增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
增强了给对象指派职责的灵活性,当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任
简化了对象之间的连接,每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句
每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则
缺点:
不能保证每个请求一定被处理,由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理
对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响
职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用
实现
角色:
抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者
客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程
代码:
1 /**抽象处理者**/ 2 public abstract class Leader { 3 private Leader next; 4 public void setNext(Leader next){ 5 this.next = next; 6 } 7 public Leader getNext(){ 8 return next; 9 } 10 11 public abstract void handleRequest(int LeaveDays); 12 13 } 14 15 /**具体处理者1**/ 16 public class ClassAdviser extends Leader{ 17 18 @Override 19 public void handleRequest(int LeaveDays) { 20 // TODO Auto-generated method stub 21 if(LeaveDays <= 2){ 22 System.out.println("班主任批准了你"+LeaveDays+"天的请假"); 23 }else{ 24 if(getNext()!= null){ 25 System.out.println( "天数过多,班主任没有审批权限" ); 26 getNext().handleRequest(LeaveDays); 27 }else{ 28 System.out.println("没有人处理这次请假"); 29 } 30 } 31 } 32 } 33 34 /**具体处理者2**/ 35 public class DepartmentHead extends Leader{ 36 37 @Override 38 public void handleRequest(int LeaveDays) { 39 // TODO Auto-generated method stub 40 if(LeaveDays <= 5){ 41 System.out.println("系主任批准了你"+LeaveDays+"天的请假"); 42 }else{ 43 if(getNext()!= null){ 44 System.out.println( "天数过多,系主任没有审批权限" ); 45 getNext().handleRequest(LeaveDays); 46 }else{ 47 System.out.println("没有人处理这次请假"); 48 } 49 } 50 } 51 } 52 53 /**具体处理者3**/ 54 public class DeanOfStudies extends Leader{ 55 56 @Override 57 public void handleRequest(int LeaveDays) { 58 // TODO Auto-generated method stub 59 if(LeaveDays <= 10){ 60 System.out.println("教务处批准了你"+LeaveDays+"天的请假"); 61 }else{ 62 if(getNext()!= null){ 63 System.out.println( "天数过多,教务处没有审批权限" ); 64 getNext().handleRequest(LeaveDays); 65 }else{ 66 System.out.println("没有人处理这次请假"); 67 } 68 } 69 } 70 } 71 72 /**具体处理者4**/ 73 public class Dean extends Leader{ 74 75 @Override 76 public void handleRequest(int LeaveDays) { 77 // TODO Auto-generated method stub 78 if(LeaveDays <= 20){ 79 System.out.println("院长批准了你"+LeaveDays+"天的请假"); 80 }else{ 81 if(getNext()!= null){ 82 System.out.println( "天数过多,院长批准你退学了" ); 83 }else{ 84 System.out.println("没有人处理这次请假"); 85 } 86 } 87 } 88 } 89 90 /**客户类**/ 91 public class Package { 92 93 public void packageTeacher(int days){ 94 Leader leader1 = new ClassAdviser(); 95 Leader leader3 = new DeanOfStudies(); 96 Leader leader4 = new Dean(); 97 Leader leader2 = new DepartmentHead(); 98 99 leader1.setNext(leader2); 100 leader2.setNext(leader3); 101 leader3.setNext(leader4); 102 leader4.setNext(leader4); 103 System.out.println( "我要请"+days+"天的假期" ); 104 leader1.handleRequest(days); 105 } 106 } 107 108 /**测试方法**/ 109 public class App { 110 public static void main( String[] args ){ 111 Package package1 = new Package(); 112 package1.packageTeacher(2); 113 System.out.println("-------------------------------"); 114 package1.packageTeacher(8); 115 System.out.println("-------------------------------"); 116 package1.packageTeacher(15); 117 System.out.println("-------------------------------"); 118 package1.packageTeacher(20); 119 System.out.println("-------------------------------"); 120 package1.packageTeacher(25); 121 System.out.println("-------------------------------"); 122 } 123 } 124 125 测试结果: 126 我要请2天的假期 127 班主任批准了你2天的请假 128 ------------------------------- 129 我要请5天的假期 130 天数过多,班主任没有审批权限 131 系主任批准了你5天的请假 132 ------------------------------- 133 我要请10天的假期 134 天数过多,班主任没有审批权限 135 天数过多,系主任没有审批权限 136 教务处批准了你10天的请假 137 ------------------------------- 138 我要请20天的假期 139 天数过多,班主任没有审批权限 140 天数过多,系主任没有审批权限 141 天数过多,教务处没有审批权限 142 院长批准了你20天的请假 143 ------------------------------- 144 我要请25天的假期 145 天数过多,班主任没有审批权限 146 天数过多,系主任没有审批权限 147 天数过多,教务处没有审批权限 148 天数过多,院长批准你退学了 149 -------------------------------