定义
使多个对象都有机会处理请求,避免了请求发送者和接收者之间的耦合关系。这些对象形成一条链,请求沿着这条链传递,直到有对象处理它为止。
场景
有多个对象可以处理请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确情况下向多个对象中的一个提交一个请求。
需要指定一组对象处理请求。
应用实例:Android View的事件分发,JS 中的事件冒泡等。
角色
Handler——抽象处理者
声明一个Handler类型的成员变量,用于持有下一个处理节点Handler对象的引用;
声明一个用于真正处理请求的抽象方法;
声明一个获取权限级别的抽象方法;
声明一个处理请求的方法根据请求权限级别决定处理请求或转交下一个处理节点Handler对象处理。
ConcreateHandler——具体处理者,实现对请求进行处理,实现获取权限级别的方法。
示例代码
/**
* 文档审批请求
*/
public class DocRequest{
/**
*级别 0 普通,1 秘密,2 机密,3 绝密
*/
int level = 0;
Object content;
public DocRequest(int level,Object content){
this.level = level;
this.content = content;
}
}
public abstract class Leader{
protected Leader nextHandler;
public void setNextHandler(LeadernextHandler){
this.nextHandler = nextHandler;
}
public final void handleRequest(DocRequest request){
if(request.level<=level()){
handler(request);
}else{
if(null!=nextHandler){
nextHandler.handleRequest(request);
}
}
}
/**
* 能审批的权限级别
*/
public abstract int level();
public abstact void handle(DocRequest);
}
/**
*办事员
*/
public calss Clerk extends Leader{
@override
public int level(){
return 0;
}
@override
public void handle(Request request){
system.out.println("职员处理普通文档:"+request.Conent.toString());
}
}
/**
*主任
*/
public class Director extends Leader(){
@override
public int level(){
return 1;
}
@override
public void handle(Request request){
system.out.println("主任审批文档:"+request.Conent.toString());
}
}
/**
* 经理
*/
public class Manager extends Leader(){
@override
public int level(){
return 2;
}
@override
public void handle(Request request){
system.out.println("经理审批文档:"+request.Conent.toString());
}
}
/**
* 老板
*/
public class Boss extends Leader(){
@override
public int level(){
return 3;
}
@override
public void handle(Request request){
system.out.println("老大审批文档:"+request.Conent.toString());
}
}
public calss Test{
public static void main(String[] args){
Clerk clerk = new Clerk();
Director director = new Director();
Manager manager = new Manager();
Boss boss = new Boss();
clerk.setNextHandler(director);
director.setNextHandler(manager);
manager.setNextHandler(boss );
DocRequest request = new DocRequest(2,"文档");
clerk.handleRequest(request);
}
缺点:增加类的数量,增加调试复杂度。每次都是从链头开始,这也是链表的缺点。