Chain of Responsibility 模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
类图:
• 当客户提交一个请求时,请求沿链传递直至有一个ConcreteHandler 对象负责处理它。
优点:
• 降低耦合度 一个对象无需知道是其他哪个对象处理其请求;
• 增强了给对象指派职责(Responsibility)的灵活性;
缺点:
• 低效;
• 不保证被处理
典型应用:
Spring MVC 的拦截器执行链 就是使用责任链模式
案例: 报销审批程序,部门经理,副总和董事长审批的金额不同。
public interface Audit {
public void setAudit(Audit audit);
public boolean approved(int amount);
}
public class DeptMgrAudit implements Audit {
private Audit audit;
public DeptMgrAudit() {
}
public void setAudit(Audit audit) {
this.audit = audit;
}
public boolean approved(int amount) {
if(amount <= 10000) {
System.out.println(amount + " is approved by department manager");
return true;
}
return audit.approved(amount);
}
}
public class VPAudit implements Audit {
private Audit audit;
public VPAudit() {
}
public void setAudit(Audit audit) {
this.audit = audit;
}
public boolean approved(int amount) {
if(amount <= 100000) {
System.out.println(amount + " is approved by VP");
return true;
}
return audit.approved(amount);
}
}
public class PresidentAudit implements Audit {
private Audit audit;
public PresidentAudit() {
}
public void setAudit(Audit audit) {
this.audit = audit;
}
public boolean approved(int amount) {
if(amount <= 1000000) {
System.out.println(amount + " is approved by President");
return true;
}
System.out.println(amount + " can not be approved");
throw new IllegalStateException("Nobody can handle it");
}
}
测试代码
public class AuditTest {
@Test(expected=IllegalStateException.class)
public void testApproved() {
Audit handler1 = new DeptMgrAudit();
Audit handler2 = new VPAudit();
handler1.setAudit(handler2);
Audit handler3 = new PresidentAudit();
handler2.setAudit(handler3);
handler1.approved(10000);
handler1.approved(50000);
handler1.approved(900000);
handler1.approved(2000000);
}
}
//output:
10000 is approved by department manager
50000 is approved by VP
900000 is approved by President
2000000 can not be approved