设计模式-责任链模式(Chain of Responsibility Pattern)-行为型

news/2024/5/19 14:50:39 标签: Android, 设计模式, 责任链模式

定义:

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

类型:

行为型

理解:

  • 定义多个请求接收者,然后把他们连接成一条链,也就是每个接受者对象里都引用了下一个接收者对象
  • 当发起一个请求时,链条的第一个接收者开始处理,如果它判断能够处理,则请求到此为止,如果不能处理,则传递给下一个接收者处理
  • 直到有一个接收者处理了该请求或者所有的接收者都无法处理为止
  • 设计模式可以用来消除大量的if/else代码
  • 生活中很多类似的例子,比如公司里的审批、报销等流程

生活中我们有时候需要点外卖,比如想吃肯德基,可能会遇到网上找了几家肯德基店要么距离远不配送,要么就没有我们想吃的这样的问题,浪费了很多时间,其实这个问题就可以用责任链模式来解决,解决问题的思路是这样的:
把不同的肯德基分店当作一个个请求接收者,将这些分店连成链状,当有订单来的时候,各个分店一个个判断能不能接单,如果能接单则开始制作配送外卖,如果不能则传递给下一个肯德基分店处理,这样用户只需要发起一个肯德基订单请求,只需要等待结果就好了,如果没有一家肯德基接单,就不吃肯德基换成其他的了,节省了很多等待和沟通成本

/**
 * 订单信息
 * @param distance 配送位置
 */
class Order(val distance:Int) {
}
/**
 * 店铺
 */
abstract class Shop(name: String, distance: Int) {
    var mNextShop: Shop? = null //下一家分店
    protected val mDistance = distance//距离
    protected val mName = name//店名
    abstract fun order(order: Order):Boolean
}
/**
 * 肯德基分店
 *
 * @author zhujie
 * @date 2019/6/6
 * @time 11:36
 */
class KfcShop(name: String, distance: Int) : Shop(name, distance) {

    override fun order(order: Order): Boolean {
        if (order.distance < mDistance) {//在配送范围
            Tool.print("[$mName] 已接单!请耐心等待!")
            return true
        }
        Tool.print("[$mName] 不在配送范围!")
        if (mNextShop != null) {
            return mNextShop!!.order(order)
        } else {
            Tool.print("没找到可以配送的店")
        }
        return false
    }
}
/**
 * 店铺管理
 *
 * @author zhujie
 * @date 2019/6/6
 * @time 12:25
 */
class ShopManager {
    private var mStartShop: Shop? = null//链首
    private lateinit var mEndShop: Shop//链尾

    init {
        Tool.print("初始化分店数据")
        val subShop1 = KfcShop("KFC分店1", 20)//分店1
        val subShop2 = KfcShop("KFC分店2", 30)//分店2
        val subShop3 = KfcShop("KFC分店3", 40)//分店3
        val subShop4 = KfcShop("KFC分店4", 50)//分店4
        val subShop5 = KfcShop("KFC分店5", 60)//分店5
        addShop(subShop1)
        addShop(subShop2)
        addShop(subShop3)
        addShop(subShop4)
        addShop(subShop5)
    }

    /**
     * 添加一个分店
     */
    fun addShop(shop: KfcShop) {
        if (mStartShop == null) {
            mStartShop = shop
            mEndShop = shop
        } else {
            mEndShop.mNextShop = shop
            mEndShop = shop
        }
    }

    /**
     * 开始下单
     */
    fun order(order: Order): Boolean {
        if (mStartShop == null) {
            return false
        }
        return mStartShop!!.order(order)
    }
}

相比较标准责任链模式,这个例子当中多了一个ShopManager管理类,用于管理所有分店,将分店组装成链式结构

运行结果:

2019-08-30 17:50:04.150:初始化分店数据
2019-08-30 17:50:04.152:[KFC分店1] 不在配送范围!
2019-08-30 17:50:04.153:[KFC分店2] 不在配送范围!
2019-08-30 17:50:04.153:[KFC分店3] 不在配送范围!
2019-08-30 17:50:04.153:[KFC分店4] 不在配送范围!
2019-08-30 17:50:04.153:[KFC分店5] 已接单!请耐心等待!

Process finished with exit code 0

类结构图如下:
在这里插入图片描述

Android_129">Android中的责任链模式

当看到责任链模式之后,相信很多朋友第一反应就是跟Android的触摸事件分发非常的相似!Android中的触摸事件,先从最顶层的ViewGroup开始,一直往下分发到各个子View里面,大致的逻辑是这样:

  • 如果某个ViewGroup想要处理这个触摸事件,则在onInterceptTouchEvent中返回true拦截该事件,该事件就不会再分发给子view,会调用该ViewGroup的onTouch方法,该onTouch方法返回true,表示消耗当前事件,否则的话会将给事件传回给父类处理
  • 如果ViewGroup不想处理该触摸事件,则分发给它的子View,如果子View的onTouch方法返回true,表示消化该事件,触摸事件就到此结束
  • 如果子view都不想处理该事件,那么就会一层一层的往上抛给他们的父类viewGroup,调用他们的onTouch方法,如果有其中一个viewGroup的onTouch返回了true,则该事件处理完毕,不再传播
  • 如果没有任何一个ViewGroup需要处理,这个触摸事件就会一层层返回到最顶层的ViewGroup,最后由Activity的onTouch方法处理
  • 如果View设置了onTouchListener,它执行的优先级比onTouchEvent要高,如果onTouchListener中的onTouch方法返回false,则View的onTouchEvent方法不会被执行
  • 触摸事件传递的顺序是:Activity->Window(PhoneWindow)->View(DecorView)
  • 同一个事件序列是从屏幕触摸到屏幕ACTION_DOWN开始的,经过0个或者多个ACTION_MOVE移动事件,最后离开屏幕ACTION_UP/ACTION_CANCEL结束
  • 正常情况下一个事件序列只能被一个View拦截处理消耗掉,如果处理了ACTION_DOWN事件,那么其他事件也会一起交给它处理,也就是onTouchEvent事件返回true,反之如果返回false,则接下来的其他事件都不会交给它处理,就好像现实生活中,领导交给你第一件事都没做好,其他事情暂时也不会交给你做
  • 如果ViewGroup的onInterceptTouchEvent返回了true,那么同一个事件其他序列也会交给它处理,而且不会再回调onInterceptTouchEvent这个方法
  • 如果View不消耗除了ACTION_DOWN以外的事件,那么这个点击事件就会消失,父元素的onTouchEvent也不会回调,但是当前view能够接收到后续的触摸事件,最终这些消失的点击事件会传递回给Activity处理
  • view没有onInterceptTouchEvent方法,只有ViewGroup有,一旦事件传递给View,它的onTouchEvent就会触发
  • View的onTouchEvent默认是返回true的,除非它是不可点击状态(clickable和longClickable同时为false),View的longClickable默认都是false的,而clickable在Button里默认是true的,像TextView默认就是false
  • View的enable属性并不影响onTouchEvent的返回值
  • onClick执行的前提是当前View是可点击的,并且接收到ACTION_DOWN和ACTION_UP事件
  • 触摸事件总是由父元素分发给子View的,子View可以通过requestDisallowInterceptTouchEvent方法在禁止父类拦截事件,但是ACTION_DOWN事件除外

优点:

  • 将请求者和接收者解耦,使得请求者不需要了解到是谁处理了这个请求,也不需要了解处理的内部细节
  • 由于链式结构的特点,使得动态增加、删除或者调整处理者顺序很容易

缺点:

  • 不能保证请求一定最终被处理
  • 当处理者过多的时候,可能会有性能方面问题

http://www.niftyadmin.cn/n/1018913.html

相关文章

【Matlab语音识别】声纹识别系统(带面板)【含GUI源码 1022期】

一、代码运行视频&#xff08;哔哩哔哩&#xff09; 【Matlab语音识别】声纹识别系统&#xff08;带面板&#xff09;【含GUI源码 1022期】 二、matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1]韩纪庆,张磊,郑铁然.语音信号处理&#xff08;第3版&#xff09;[M].…

【Matlab语音识别】MFCC+VQ说话人识别系统【含GUI源码 1153期】

一、代码运行视频&#xff08;哔哩哔哩&#xff09; 【Matlab语音识别】MFCCVQ说话人识别系统【含GUI源码 1153期】 二、matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1]韩纪庆,张磊,郑铁然.语音信号处理&#xff08;第3版&#xff09;[M].清华大学出版社&#xf…

基于EventBus3.1.1源码分析

EventBus的使用&#xff1a; 在分析源码前先来回顾一下EventBus怎么用的,开源地址&#xff1a;GitHub 在app项目build.gradle中添加依赖&#xff1a; implementation org.greenrobot:eventbus:3.1.1然后注册订阅者&#xff0c;官方推荐是在onStart和onStop里注册和取消注册 …

03.从0到1,软件基础平台供应商团队建设的阶段偏向

当我们整体转入java方向时&#xff0c;有着10几年.net工作经验的我们&#xff0c;又从0起步&#xff0c;与整体体系的成员竞争。就像《人月神话》中描述的那样&#xff0c;我们经过了大量会议的2020年&#xff1b;走过了象征性双休的2021年&#xff1b;在困苦中迎来了相对正常的…

【Matlab语音识别】语音识别信号灯图像模拟控制【含GUI源码 757期】

一、代码运行视频&#xff08;哔哩哔哩&#xff09; 【Matlab语音识别】语音识别信号灯图像模拟控制【含GUI源码 757期】 二、matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1]韩纪庆,张磊,郑铁然.语音信号处理&#xff08;第3版&#xff09;[M].清华大学出版社&am…

Android 模块化/组件化 理解

项目模块化/组件的个人理解 随着项目越来越大&#xff0c;编译的时间会越来越长&#xff0c;参与开发测试的人也会越来越多&#xff0c;各个功能模块之间也会越来越耦合难以复用&#xff0c;模块化和组件化就是为了提高开发测试的效率&#xff0c;降低功能模块之间的耦合性&am…

【Matlab语音识别】智能语音识别门禁系统【含GUI源码 596期】

一、代码运行视频&#xff08;哔哩哔哩&#xff09; 【Matlab语音识别】智能语音识别门禁系统【含GUI源码 596期】 二、matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1]韩纪庆,张磊,郑铁然.语音信号处理&#xff08;第3版&#xff09;[M].清华大学出版社&#xff…

05.从0到1,怎么去构建下一个10年

1.身处的环境 经过三年的累进&#xff0c;我们的产品在生产环境应用中初露锋芒&#xff0c;业务的完整性/初步的性能改善/产品交付难度的降低以及统一流程平台的全能力构建&#xff0c;对于企业基础应用来说具备了较高的实用性。从.net走向了java,在最新技术与多年的业务磨练下…