美文网首页
事件分发的设计模式

事件分发的设计模式

作者: 锐_nmpoi | 来源:发表于2017-03-31 21:37 被阅读995次

从 Android 源码 发现设计模式

前面已经写过了事件的分发机制,以及源码的分析了。每当用户接触到了屏幕的时候,Android会将对应的事件包装成一个事件从对象ViewTree的顶部从上到下的开始分发传递。而在ViewGroup中,ViewGroup中执行事件的派发分发是通过dispatchTouchEvent。

在这个方法中,我们可以很清楚的看到ViewGroup就会遍历所有的子View。拿到子View的时候,源码中做了几个判断,判断这个子View是否符合条件。如果不满足则直接选取下一个子View。 拿到符合条件的子View,那么将调用 dispatchTransformedTouchEvent 这个方法。 在dispatchTransformedTouchEvent方法中就调用了child.dispatchTouchEvent(event)。

从上源码中可以的知到最重要的一点就是,ViewGroup的事件投递的递归调用就类似一个责任链,不断的从子View中寻找能处理这个事件的子View,一旦找到了这个责任者,那么将由这个责任者持有并且消费这个事件。从View中的 onTouchEvent 方法的返回值可以很清楚的看到这一点,当onTouchEvent 返回 false 代表 ,那么意味着这个不是该事件的负责人,当返回了true,此时会持有这个事件,并不向外再传递了。

责任链模式 介绍

从ViewGroup对于事件的分发来说,一个传递给一个,形成了一个链子,最后从链子中找到一个来处理这个事件。把这种形式抽象出来,其实就是责任链模式,我们把多个节点首尾相连所构成的模式称为链。对于这种构成,把每一个节点都看做一个对象,每个对象拥有不同的处理逻辑,然后将一个责任从链子的首端出发,沿着链子依次传递给每个节点的对象,直到有个对象处理这个责任。

责任链模式 定义

使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理他为止。

责任链模式 使用场景

使用场景就和ViewGroup一样,多个对象处理一个请求,但是具体由哪个对象处理,是动态决定的。

责任链模式 UML类图

从上面的类图我们可以看到的一点就是,因为在责任链中的请求和对应的处理规则都是不尽相同的,在这种情况的状态下,就要把请求类和处理规则进行了封装,封装到一个独立的对象,那么同样从链子的首端开始处理分发,不同的请求也会找到相应的处理规则来处理请求。

用例子来说明

抽象请求者

public abstract class AbstractRequest {

    private Object obj ;
    
    public AbstractRequest(Object obj){
        this.obj = obj;
    }
    
    public Object getContent(){
        return obj;
    }
    
    public abstract int getRequestLevel();
}

抽象处理者

public abstract class AbstractHandler {

    private AbstractHandler nextHandler;
    
    public void handleRequest(AbstractRequest request){
        if(request.getRequestLevel() == getHandleLevel()){
            handle(request);
        }else{
            if(nextHandler != null){
                nextHandler.handleRequest(request);
            }else{
                System.out.println("这个请求没有相对应的 Handler 来处理");
            }
        }
    }

    public void setNextHandler(AbstractHandler nextHandler){
        this.nextHandler = nextHandler;
    }
    
    protected abstract void handle(AbstractRequest request) ;

    protected  abstract int getHandleLevel();
    
}

请求者

public class Request_1 extends AbstractRequest{

    public Request_1(Object obj) {
        super(obj);
    }

    @Override
    public int getRequestLevel() {
        return 1;
    }

}

public class Request_2 extends AbstractRequest{

    public Request_2(Object obj) {
        super(obj);
    }

    @Override
    public int getRequestLevel() {
        return 2;
    }

}

public class Request_3 extends AbstractRequest{

    public Request_3(Object obj) {
        super(obj);
    }

    @Override
    public int getRequestLevel() {
        return 3;
    }

}

处理者

public class Handler_1 extends AbstractHandler {

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("处理 request 的等级为 : " +request.getRequestLevel() );
    }

    @Override
    protected int getHandleLevel() {
        return 1;
    }

}

public class Handler_2 extends AbstractHandler {

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("处理 request 的等级为 : " +request.getRequestLevel() );
    }

    @Override
    protected int getHandleLevel() {
        return 2;
    }

}

public class Handler_3 extends AbstractHandler {

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("处理 request 的等级为 : " +request.getRequestLevel() );
    }

    @Override
    protected int getHandleLevel() {
        return 3;
    }

}

执行

public static void main(String[] args) {
        AbstractHandler handler_1 = new Handler_1 () ;
        AbstractHandler handler_2 = new Handler_2 () ;
        AbstractHandler handler_3 = new Handler_3 () ;
        
        //连成责任链
        handler_1.setNextHandler(handler_2);
        handler_2.setNextHandler(handler_3);
        
        AbstractRequest request_1 = new Request_1("Request_1");
        AbstractRequest request_2 = new Request_2("Request_2");
        AbstractRequest request_3 = new Request_3("Request_3");
        
        //都是从首端开始传送请求
        handler_1.handleRequest(request_1);
        handler_1.handleRequest(request_2);
        handler_1.handleRequest(request_3);
    }

运行结果

处理 request 的等级为 : 1
处理 request 的等级为 : 2
处理 request 的等级为 : 3

总结

责任链模式:

优点:显而易见,可以对链中请求者和处理者关系解耦,提高了代码的灵活性。

缺点:每次处理都要从头开始遍历,如果处理者太多牌,那么遍历必然会影响性能。

相关文章

  • Redis的IO多路复用——单线程的理解(Redis6.0之后的

    Reactor设计模式 Reactor 设计模式是一种事件驱动的设计模式,分发器(Dispatcher)使用多路分...

  • Android事件分发流程(一)责任链设计模式

    责任链设计模式 简单介绍 View的事件分发机制是责任链(Chain of Responsibility)设计模式...

  • 事件分发原理?

    事件分发原理? 事件分发原理? 参考答案:事件分发,其实就是一个责任链的变种,这个责任链,是一个设计模式。 在An...

  • 事件分发的设计模式

    从 Android 源码 发现设计模式 前面已经写过了事件的分发机制,以及源码的分析了。每当用户接触到了屏幕的时候...

  • ViewGroup事件分发

    责任链模式定义(事件分发就是采用责任链模式) 建议先看View的事件分发 一、事件分发的关键方法和开始位置 二、查...

  • javascript设计模式(2)

    技巧型设计模式 27.链模式 return this; 28.委托模式 点击事件委托到父元素上,内存外泄,数据分发...

  • Android事件分发流程(二)源码解析

    这是一个系列文章,如果没有责任链设计模式的基础知识,请移步Android事件分发流程(一)责任链设计模式 接着上文...

  • Android事件分发浅析及设计模式

    android中的事件分发,简单来说就是 dispatchTouchEvent、onInterceptTouchE...

  • 事件分发

    事件分发原理: 责任链模式,事件层层传递,直到被消费。 View 的 dispatchTouchEvent 主要用...

  • Android 事件分发机制

    总结 View 事件分发的本质是递归。 递归的本质是,任务的下发和结果的上报。 View 事件分发设计成递归,是为...

网友评论

      本文标题:事件分发的设计模式

      本文链接:https://www.haomeiwen.com/subject/swxbottx.html