责任链模式
将能够处理同一类请求的对象连成一条链,所提交的请求将沿着这条链传递,链上的对象逐个判断是否有能力处理该请求,如果有则处理,如果没有则将请求传递给下一个对象处理。
场景举例
模式结构
- Requester请求者:请求类
- AbstractHandler抽象处理者:由于各级对象都具有相同的处理能力,所以有一个公共的抽象父接口
- ConcreteHandler具体处理者:具有不同处理能力的处理类
代码
Requester请求者
1 2 3 4 5 6 7 8 9
|
@Date public class Student { private String name; private int leaveDays; private String reason; }
|
AbstractHandler抽象处理者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public abstract class Leader { protected String name; protected Leader nextHandler; public Leader(String name) { super(); this.name = name; } public void setNextHandler(Leader nextHandler) { this.nextHandler = nextHandler; } protected abstract void handleRequest(Student student); }
|
ConcreteHandler抽象处理者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
public class Assistant extends Leader { public Assistant(String name) { super(name); } @Override protected void handleRequest(Student student) { if(student.getLeaveDays()<3){ System.out.println("辅导员:"+this.name+"批准"+student.getName()+"的请假"); }else{ if(this.nextHandler!=null){ this.nextHandler.handleRequest(student); } } } }
public class Dean extends Leader { public Dean(String name) { super(name); } @Override protected void handleRequest(Student student) { if(student.getLeaveDays()<10){ System.out.println("院长:"+this.name+"批准"+student.getName()+"的请假"); }else{ if(this.nextHandler!=null){ this.nextHandler.handleRequest(student); } } } }
public class HeadMaster extends Leader { public HeadMaster(String name) { super(name); } @Override protected void handleRequest(Student student) { if(student.getLeaveDays()<30){ System.out.println("校长:"+this.name+"批准"+student.getName()+"的请假"); }else{ System.out.println("请假被拒绝"); } } }
|
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Client { public static void main(String[] args) { Leader assistant=new Assistant("张三"); Leader dean=new Dean("李四"); Leader headMaster=new HeadMaster("王五"); assistant.setNextHandler(dean); dean.setNextHandler(headMaster); Student student=new Student("赵六",15,"回家探亲"); assistant.handleRequest(student); } }
|
非链表实现责任链
上述代码通过链表的方式定义责任链,而往往通过集合、数组生成责任链更加实用。实际上,在很多项目中,每个具体的Handler并不是由开发团队定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义COR链就很困难。
总结
责任链模式对于请求的处理是不知道最终处理者是谁,所以是运行动态寻找并指定;而命令模式中对于命令的处理时在创建命令是已经显式或隐式绑定了接收者。
使用场景
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
- 处理一个请求的对象集合应被动态指定
缺点
对于每一个请求都需要遍历职责链,性能是个问题