Android 责任链模式

源码地址

介绍

它是一种行为型设计模式之一。它的每一个节点都可以看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,这就是责任链模式。

使用场景

  1. 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
  2. 在请求处理者不明确的情况下,向多个对象中的一个提交一个请求。
  3. 需要动态指定一组对象处理请求。

示例一

说明:此为简化版代码,分为抽象处理者,具体的处理者。代码如下:

  1. 抽象处理者

    public abstract class Handler {
        protected Handler successor;    //下一节点的处理者
    
        /**
         * 请求处理
         * @param condition 请求条件
         */
        public abstract void handleRequest(String condition);
    }
    
  2. 具体的处理者1

    public class ConcreteHandler1 extends Handler {
        @Override
        public void handleRequest(String condition) {
            if (condition.equals("ConcreteHandler1")) {
                System.out.println("ConcreteHandler1 handled");
            } else {
                successor.handleRequest(condition);
            }
        }
    }
    
  3. 具体的处理者2

    public class ConcreteHandler2 extends Handler {
        @Override
        public void handleRequest(String condition) {
            if (condition.equals("ConcreteHandler2")) {
                System.out.println("ConcreteHandler2 handled");
            } else {
                successor.handleRequest(condition);
            }
        }
    }
    
  4. 客户类

    public class Client {
        public static void main(String[] args) {
            //构造一个ConcreteHandler1对象
            ConcreteHandler1 handler1 = new ConcreteHandler1();
            //构造一个ConcreteHandler2对象
            ConcreteHandler2 handler2 = new ConcreteHandler2();
            //设置handler1的下一个节点
            handler1.successor = handler2;
            //设置handler2的下一个节点
            handler2.successor = handler1;
            //处理请求
            handler1.handleRequest("ConcreteHandler2");
        }
    }
    

示例二

说明:抽象处理者,抽象请求者,请求者,处理者。代码如下:

  1. 抽象处理者

    public abstract class AbstractHandler {
        protected AbstractHandler nextHandler;    //下一节点的处理者对象
    
        /**
         * 请求处理
         * @param request 请求条件
         */
        public final void handleRequest(AbstractRequest request) {
            //判断当前处理者对象的处理级别是否与请求者的处理级别一致
            if (getHandleLevel() == request.getRequestLevel()) {
                //一致则由该处理对象处理
                handle(request);
            } else {
                //否则将该请求对象转发给下一个节点上的请求对象
                if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                } else {
                    //所有处理者对象均不能处理该请求时输出
                    System.out.println("All of handler can not handle the request");
                }
            }
        }
    
        /**
         * 获取处理者对象的处理级别
         * @return  处理级别
         */
        protected abstract int getHandleLevel();
    
        /**
         * 每个处理者对象的具体处理方式
         * @param request   请求者对象
         */
        protected abstract void handle(AbstractRequest request);
    }
    
  2. 抽象请求者

    public abstract class AbstractRequest {
        private Object obj; //处理对象
    
        public AbstractRequest(Object obj) {
            this.obj = obj;
        }
    
        public Object getContent() {
            return obj;
        }
    
        /**
         * 获取请求级别
         * @return  请求级别
         */
        public abstract int getRequestLevel();
    }
    
  3. 请求者

    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;
        }
    }
    
  4. 处理者

    public class Handler1 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 1;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler1 handle request:" + request.getRequestLevel());
        }
    }
    
    public class Handler2 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 2;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler2 handle request:" + request.getRequestLevel());
        }
    }
    
    public class Handler3 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 3;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler3 handle request:" + request.getRequestLevel());
        }
    }
    
  5. 客户类

    public class Client {
        public static void main(String[] args) {
            //构造3个处理者对象
            AbstractHandler handler1 = new Handler1();
            AbstractHandler handler2 = new Handler2();
            AbstractHandler handler3 = new Handler3();
    
            //设置当前处理者对象下一个节点的处理者对象
            handler1.nextHandler = handler2;
            handler2.nextHandler = handler3;
    
            //构造3个请求者对象
            AbstractRequest request1 = new Request1("Request1");
            AbstractRequest request2 = new Request2("Request2");
            AbstractRequest request3 = new Request3("Request3");
    
            //总是从链式的首端发起请求
            handler1.handleRequest(request1);
            handler1.handleRequest(request2);
            handler1.handleRequest(request3);
        }
    }
    

示例三

说明:小明出差学些新技术,其中花费了5w元,于是小明去找组长报销费用。。。代码如下:

  1. 抽象领导者

    public abstract class Leader {
        //上一级领导处理者
        protected Leader nextHandler;
    
        /**
         * 处理报账请求
         * @param money 能批复的报账额度
         */
        public final void handleRequest(int money) {
            if (money <= limit()) {
                handle(money);
            } else {
                if (nextHandler != null) {
                    nextHandler.handleRequest(money);
                }
            }
        }
    
        /**
         * 自身能够批复的额度权限
         * @return  额度
         */
        protected abstract int limit();
    
        /**
         * 处理报账行为
         * @param money 具体金额
         */
        protected abstract void handle(int money);
    }
    
  2. 具体的领导者

    public class GroupLeader extends Leader {
    
        @Override
        protected int limit() {
            return 1000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("组长批复报销" + money + "元");
        }
    }
    
    public class Director extends Leader {
    
        @Override
        protected int limit() {
            return 5000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("主管批复报销" + money + "元");
        }
    }
    
    public class Manager extends Leader {
    
        @Override
        protected int limit() {
            return 10000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("经理批复报销" + money + "元");
        }
    }
    
    public class Boss extends Leader {
    
        @Override
        protected int limit() {
            return Integer.MAX_VALUE;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("老板批复报销" + money + "元");
        }
    }
    
  3. 客户类小明

    public class XiaoMing {
        public static void main(String[] args) {
            //构造各个领导对象
            GroupLeader groupLeader = new GroupLeader();
            Director director = new Director();
            Manager manager = new Manager();
            Boss boss = new Boss();
    
            //设置上一级领导处理者对象
            groupLeader.nextHandler = director;
            director.nextHandler = manager;
            manager.nextHandler = boss;
    
            //发起报账申请
            groupLeader.handleRequest(50000);
        }
    }
    

    小明先找组长报账,然后组长找到主管,主管找到经理,经理最后找到老板解决。

    当然也可以直接跳过某个人。

对于责任链中的一个处理者对象,其只有两种行为,一是处理请求,二是将请求转送给下一个节点,不允许某个处理者对象在处理了请求后又将请求转送给上一个节点的情况。

对于一条责任链来说,一个请求最终只有两种情况,一个呗某个处理对象所处理,另一个是所有对象均未对其处理,对于前一种情况我们称该责任链为纯的责任链,对于后一种情况我们称为不纯的责任链,在实际应用中,我们所见到的责任链模式大多为不纯的责任链。

Android 源码中的实现

事件的分发处理。

责任链模式实战

说明:有序广播的处理。源码地址

  1. 广播接收者

    public class FirstReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //获取Intent中附加的限制值
            int limit = intent.getIntExtra("limit", -1001);
            //如果限制值等于1000,则处理,否则继续转发给下一个Receiver
            if (limit == 1000) {
                //获取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    
                //终止广播
                abortBroadcast();
            } else {
                //添加信息发送给下一个Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from FirstReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
    public class SecondReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //获取Intent中附加的限制值
            int limit = intent.getIntExtra("limit", -1001);
            //如果限制值等于100,则处理,否则继续转发给下一个Receiver
            if (limit == 100) {
                //获取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
    
                //获取上一个Receiver增加的消息
                Bundle bundle = getResultExtras(true);
                String str = bundle.getString("new");
                Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show();
    
                //终止广播
                abortBroadcast();
            } else {
                //添加信息发送给下一个Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from SecondReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
    public class ThirdReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //获取Intent中附加的限制值
            int limit = intent.getIntExtra("limit", -1001);
            //如果限制值等于10,则处理,否则继续转发给下一个Receiver
            if (limit == 10) {
                //获取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
    
                //获取上一个Receiver增加的消息
                Bundle bundle = getResultExtras(true);
                String str = bundle.getString("new");
                Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show();
    
                //终止广播
                abortBroadcast();
            } else {
                //添加信息发送给下一个Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from ThirdReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
  2. 部分清单文件数据

    <receiver android:name="com.yan.iterator.FirstReceiver">
        <intent-filter android:priority="1000">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    <receiver android:name="com.yan.iterator.SecondReceiver">
        <intent-filter android:priority="100">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    <receiver android:name="com.yan.iterator.ThirdReceiver">
        <intent-filter android:priority="10">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    
  3. MainActivity

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction("com.yan.iterator.action.ORDER_BROADCAST");
                    intent.putExtra("limit", 100);
                    intent.putExtra("msg", "Message from MainActivity");
                    sendOrderedBroadcast(intent, null);
                }
            });
        }
    }
    

总结

  • 优点

    可以对请求者和处理者关系解耦,提高代码的灵活性。

  • 缺点

    对链中请求处理者的遍历,如果处理者太多,那么遍历必定会影响性能,特别是在一些递归调用中,要慎重。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 119,172评论 16 133
  • 2017年5月17日 Kylin_Wu 标注(★☆)为考纲明确给出考点(必考) 常见手机系统(★☆) And...
    Azur_wxj阅读 1,361评论 0 10
  • #Android 基础知识点总结 ---------- ##1.adb - android debug bridg...
    Mythqian阅读 2,274评论 2 11
  • 上篇文章介绍了IPC机制的基本概念以及简单使用,文章链接:Android 关于IPC机制的理解(一) 这篇文章主要...
    老实任阅读 364评论 0 2
  • 在我看来,小说的本质是通过讲述别人的故事来解决本人的问题。 人性本来如此,一切的目的都是为了解决现实的问题。读小说...
    小阿尔阅读 310评论 1 1