Java设计模式——责任链模式

          责任链模式,顾名思义,多个对象可以处理同一个请求,但是用哪个对象处理请求,是动态的,对象成链式结构,将请求一级一级向下传,处理则截断,否则继续向下传递,这就是责任链模式。

        android里的屏幕触摸事件就是用的这种模式,父布局先收到触摸事件,如果父布局选择处理,子view则收不到触摸事件,反之父布局将事件传给子布局,后面有时间我会写一篇关于android触摸事件传递的源码讲解,在这之前先了解一下责任链模式。

一、定义

1、多个对象有机会处理同一个请求,从而避免了请求的发送者和各个接收者之间的耦合关系。将这些接收者对象连成一条链,直到有从头到尾一次调用处理请求。

UML图:

Handler:抽象处理者,声明一个处理请求的方法,并在其中保存一个下一节点的处理者的对象引用

ConcreteHandler1/2:具体处理者,对请求进行处理,如果不能处理则将请求发送给下一个节点的处理者处理

二、使用场景

多个对象有机会处理同一个请求,但是用哪个对象处理请求,是动态的

三、示例

先写一个抽象类作为父类:

public abstract class EventHandler {

    public EventHandler eventHandler;//下一个节点

    public abstract void doSomething(String name);//待处理的请求

}


然后创建三个可以处理同一个请求的对象:

public class MyHandler1 extends EventHandler {

    @Override
    public void doSomething(String name) {
        if ("MyHandler1".equals(name)) {
            Log.e("tag", "MyHandler1 处理了事件");
        } else {
            if (eventHandler != null)
                eventHandler.doSomething(name);
        }
    }
}

 

public class MyHandler2 extends EventHandler {

    @Override
    public void doSomething(String name) {
        if ("MyHandler2".equals(name)) {
            Log.e("tag", "MyHandler2 处理了事件");
        } else {
            if (eventHandler != null)
                eventHandler.doSomething(name);
        }
    }
}

 

public class MyHandler3 extends EventHandler {

    @Override
    public void doSomething(String name) {
        if ("MyHandler3".equals(name)) {
            Log.e("tag", "MyHandler3 处理了事件");
        } else {
            if (eventHandler != null)
                eventHandler.doSomething(name);
        }
    }
}


好了,不用解释什么,代码几乎都是一样的,使用起来很简单:

客户类:

        MyHandler1 handler1 = new MyHandler1();
        MyHandler2 handler2 = new MyHandler2();
        MyHandler3 handler3 = new MyHandler3();
        //设置MyHandler1的下一个节点
        handler1.eventHandler = handler2;
        //设置MyHandler2的下一个节点
        handler2.eventHandler = handler3;
        handler1.doSomething("MyHandler2");


传入MyHandler2,这个事件将会被MyHandler2处理,并且截断不再传给MyHandler3

四、责任链模式进阶

上面我们说的是一个简化版的通用模式代码,因为对于请求者来说,其形式是固定的,就是一个字符串,我们判断接收者是否能处理请求的时候,只是判断字符串是否匹配,然而在大多数情况下,这样显然是不满足需求的,所以我们也需要对请求者进行封装,把请求者也作为一个独立的对象:

 

五,进阶示例 

首先我们来看抽象处理者AbsteactHandler

    public abstract class AbstractHandler {

        protected AbstractHandler next;

        public final void handleRequest(AbstractRequest request) {
            if (getHandleLevel() == request.getRequestLevel()) {
                handle(request);
            } else {
                if (next != null) {
                    next.handleRequest(request);
                } else {
                    System.out.print("所有处理者皆不能处理请求");
                }
            }
        }

        /**
         * 获取处理者对象的级别
         *
         * @return 级别
         */
        public abstract int getHandleLevel();

        /**
         * 每个处理者对象的处理方式
         *
         * @param request 请求者对象
         */
        public abstract void handle(AbstractRequest request);
    }

这种情况下我们的责任转发逻辑由抽象处理者控制,而对于抽象请求者,其内部也声明了请求级别的方法,什么级别的处理者处理什么级别的请求

    public abstract class AbstractRequest {

        /**
         * 处理对象
         */
        private Object obj;

        public AbstractRequest(Object obj) {
            this.obj = obj;
        }

        public Object getObj() {
            return obj;
        }

        /**
         * 获取请求级别
         *
         * @return 级别
         */
        public abstract int getRequestLevel();
    }

接着我们事先三个请求者和处理者,这里就不多说了:

    public class Request1 extends AbstractRequest {

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

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

    public class Request2 extends AbstractRequest {

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

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

    public class Request3 extends AbstractRequest {

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

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

    public class Handler1 extends AbstractHandler {
        @Override
        public int getHandleLevel() {
            return 1;
        }

        @Override
        public void handle(AbstractRequest request) {
            System.out.print(getClass().getSimpleName() + "处理了请求:" + obj);
        }
    }

    public class Handler2 extends AbstractHandler {
        @Override
        public int getHandleLevel() {
            return 2;
        }

        @Override
        public void handle(AbstractRequest request) {
            System.out.print(getClass().getSimpleName() + "处理了请求:" + obj));
        }
    }

    public class Handler3 extends AbstractHandler {
        @Override
        public int getHandleLevel() {
            return 3;
        }

        @Override
        public void handle(AbstractRequest request) {
            System.out.print(getClass().getSimpleName() + "处理了请求:" + obj));
        }
    }

下面是客户类,大家可以自行尝试:

    public static void main(String[] args) {

        //构造三个处理者
        AbstractHandler handler1 = new Handler1();
        AbstractHandler handler2 = new Handler2();
        AbstractHandler handler3 = new Handler3();

        handler1.next = handler2;
        handler2.next = handler3;

        //构造三个请求者
        AbstractRequest request1 = new Request1("Request1");
        AbstractRequest request2 = new Request2("Request2");
        AbstractRequest request3 = new Request3("Request3");

        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
        handler1.handleRequest(request3);

    }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值