1.定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
2.类图
3.代码示例
1 package com.zhaoyangwoo.chainOfResponsibility; 2 3 /** 4 * Created by john on 16/6/16. 5 * 职责链模式,经费审批场景 6 */ 7 public class Responsibility { 8 9 public static void main(String[] args) { 10 11 //zhaoyanghoo报销100元 12 Request request = new Request(); 13 request.setName("zhaoyanghoo"); 14 request.setLevel(new Level(100)); 15 16 ApprovalUtil.handleApproval(request).print(); 17 18 //zhaoyanghoo报销100元 19 Request request2 = new Request(); 20 request2.setName("xiaohong"); 21 request2.setLevel(new Level(10000)); 22 23 ApprovalUtil.handleApproval(request2).print(); 24 25 26 //zhaoyanghoo报销100元 27 Request request3 = new Request(); 28 request3.setName("xiaoming"); 29 request3.setLevel(new Level(10000000)); 30 ApprovalUtil.handleApproval(request3).print(); 31 32 } 33 34 } 35 36 /** 37 * 用这个工具类封装内部关系,client只需要知道ApprovalUtil,而不需要跟manage/director等关联 38 */ 39 class ApprovalUtil { 40 static Approval manage, director, cfo; 41 42 static { 43 manage = new Manager(); 44 director = new Director(); 45 cfo = new CFO(); 46 47 manage.setSuccessor(director); 48 director.setSuccessor(cfo); 49 } 50 51 static Response handleApproval(Request request) { 52 return manage.handleApproval(request); 53 } 54 } 55 56 57 /** 58 * 抽象类,审批人 59 */ 60 abstract class Approval { 61 62 public void setSuccessor(Approval successor) { 63 this.successor = successor; 64 } 65 66 protected abstract Level getLevel(); 67 68 //后继审批人 69 protected Approval successor; 70 71 72 public final Response handleApproval(Request request) { 73 if (request == null || request.getLevel() == null) return null; 74 if (this.getLevel() != null && this.getLevel().higherThen(request.getLevel())) { 75 return this.hanlder(request); 76 } else if (this.successor != null) { 77 return this.successor.handleApproval(request); 78 } else 79 return new Response("无人能处理" + request.getName() + "的报销请求"); 80 } 81 82 protected abstract Response hanlder(Request request); 83 } 84 85 /** 86 * 经理只审批500元内经费 87 */ 88 class Manager extends Approval { 89 90 //最多审批500元 91 private final static Level level = new Level(500); 92 93 @Override 94 protected Level getLevel() { 95 return level; 96 } 97 98 @Override 99 public Response hanlder(Request request) { 100 return new Response(String.format("经理审批了%s的%d元报销", request.getName(), request.getLevel().getAmount())); 101 } 102 } 103 104 /** 105 * 总监审批1000元内的报销 106 */ 107 class Director extends Approval { 108 109 //最多审批1000元 110 private final static Level level = new Level(1000); 111 112 @Override 113 protected Level getLevel() { 114 return level; 115 } 116 117 @Override 118 public Response hanlder(Request request) { 119 return new Response(String.format("总监审批了%s的%d元报销", request.getName(), request.getLevel().getAmount())); 120 } 121 } 122 123 /** 124 * CFO审批100000 125 */ 126 class CFO extends Approval { 127 128 //最多审批500元 129 private final static Level level = new Level(100000); 130 131 @Override 132 protected Level getLevel() { 133 return level; 134 } 135 136 @Override 137 public Response hanlder(Request request) { 138 return new Response(String.format("CFO审批了%s的%d元报销", request.getName(), request.getLevel().getAmount())); 139 } 140 } 141 142 //请求模拟类 143 class Request { 144 public Level getLevel() { 145 return level; 146 } 147 148 public void setLevel(Level level) { 149 this.level = level; 150 } 151 152 //请求的级别 153 Level level; 154 155 //姓名 156 String name; 157 158 public String getName() { 159 return name; 160 } 161 162 public void setName(String name) { 163 this.name = name; 164 } 165 } 166 167 //请求级别类 168 class Level { 169 170 public Level(int amount) { 171 this.amount = amount; 172 } 173 174 public int getAmount() { 175 return amount; 176 } 177 178 //报销金额 179 private final int amount; 180 181 //如果高于当前金额,则无法处理 182 public boolean higherThen(Object obj) { 183 if (obj == null) return false; 184 if (obj == this) { 185 return true; 186 } else if (obj instanceof Level) { 187 return this.amount > ((Level) obj).amount; 188 } 189 return false; 190 } 191 } 192 193 //相应模拟类 194 class Response { 195 public Response(String message) { 196 this.message = message; 197 } 198 199 public String getMessage() { 200 return message; 201 } 202 203 public void setMessage(String message) { 204 this.message = message; 205 } 206 207 //审批结果 208 private String message; 209 210 //打印审批结果 211 public void print() { 212 System.out.println(message); 213 } 214 }
4.应用场景举例
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求
5.JDK源码中的模式实现
java.util.logging.Logger类应用了责任链模式
public void log(LogRecord record) { if (!isLoggable(record.getLevel())) { return; } Filter theFilter = filter; if (theFilter != null && !theFilter.isLoggable(record)) { return; } // Post the LogRecord to all our Handlers, and then to // our parents' handlers, all the way up the tree. Logger logger = this; while (logger != null) { final Handler[] loggerHandlers = isSystemLogger ? logger.accessCheckedHandlers() : logger.getHandlers(); for (Handler handler : loggerHandlers) { handler.publish(record); } final boolean useParentHdls = isSystemLogger ? logger.useParentHandlers : logger.getUseParentHandlers(); if (!useParentHdls) { break; } logger = isSystemLogger ? logger.parent : logger.getParent(); } } public boolean isLoggable(Level level) { if (level.intValue() < levelValue || levelValue == offValue) { return false; } return true; }
6.思考
- 如何控制链的长度,以保证性能
可以在抽象类中添加一个static final的常量,标志最长的链有MAX个元素,一个static的set类型变量,setSuccessor方法中将handler添加到set变量中,比较MAX和Set.size()。
7.参考