Android设计模式详解之责任链模式

前言

责任链模式是行为型设计模式;

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

使用场景:

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

UML类图:
责任链UML
AbstractHandler:抽象处理者角色;
属性:
nextHandler:保持对下一个节点处理者对象的引用;
方法:
handleRequest(AbstractRequest request):处理请求;
getHandleLevel():获取处理者对象的处理级别;
handle():每个处理者对象的具体处理方式;

AbsRequest:抽象请求者角色;
属性:
obj:处理对象;
方法:
getContent():获取具体的处理对象;
getRequestLevel():获取请求级别;

ContrectHandler1ContrectHandler2ContrectHandler3 : 具体的处理者对象;
ContrectRequest1ContrectRequest2ContrectRequest3 : 具体的请求者对象;

Client:客户端调用者;

模板代码

  • 定义抽象请求者,AbstractRequest

/**
 * 抽象请求者
 * @obj 要处理的对象
 */
abstract class AbstractRequest(private val obj: Any) {
    /**
     * 具体的内容对象
     */
    fun getContent(): Any {
        return obj
    }

    /**
     * 获取请求级别
     * @return 请求级别
     */
    abstract fun getRequestLevel(): Int

}
  • 定义抽象处理者,AbstractHandler
/**
 * 抽象处理者
 */
abstract class AbstractHandler {
    //下一个节点的处理者对象
    var nextHandler: AbstractHandler? = null

    /**
     * 处理请求
     * @param request 请求者对象
     */
    fun handleRequest(request: AbstractRequest) {
        //判断当前处理者对象的处理级别与请求者的处理级别是否一致
        if (getHandleLevel() == request.getRequestLevel()) {
            //一致则交给该处理对象进行处理
            handle(request)
        } else {
            //否则将该请求交给下一个节点的处理者进行处理
            nextHandler?.handleRequest(request)
        }
    }

    /**
     * 获取处理者对象的处理级别
     * @return 处理级别
     */
    protected abstract fun getHandleLevel(): Int

    /**
     * 每个处理者对象的具体处理方式
     * @param request 请求者对象
     */
    protected abstract fun handle(request: AbstractRequest)
}
  • 分别定义处理者1、处理者2、处理者3,Handler1Handler2Handler3;
/**
 * 处理者1
 */
class Handler1 : AbstractHandler() {
    override fun getHandleLevel(): Int {
        return 1
    }

    override fun handle(request: AbstractRequest) {
        println("Handler1 handle request:${request.getRequestLevel()}")
    }
}

/**
 * 处理者2
 */
class Handler2 : AbstractHandler() {
    override fun getHandleLevel(): Int {
        return 2
    }

    override fun handle(request: AbstractRequest) {
        println("Handler2 handle request:${request.getRequestLevel()}")
    }
}

/**
 * 处理者3
 */
class Handler3 : AbstractHandler() {
    override fun getHandleLevel(): Int {
        return 3
    }

    override fun handle(request: AbstractRequest) {
        println("Handler3 handle request:${request.getRequestLevel()}")
    }
}
  • 分别定义请求者1、请求者2、请求者3,Request1Request2Request3
/**
 * 请求者1
 */
class Request1(obj: Any) : AbstractRequest(obj) {
    override fun getRequestLevel(): Int {
        return 1
    }
}

/**
 * 请求者2
 */
class Request2(obj: Any) : AbstractRequest(obj) {
    override fun getRequestLevel(): Int {
        return 2
    }
}

/**
 * 请求者3
 */
class Request3(obj: Any) : AbstractRequest(obj) {
    override fun getRequestLevel(): Int {
        return 3
    }
}
  • 编写测试代码,进行链式调用;
object Test {

    @JvmStatic
    fun main(args: Array<String>) {
        //构造3个处理者对象
        val handler1 = Handler1()
        val handler2 = Handler2()
        val handler3 = Handler3()

        //设置处理者对应下一个节点
        handler1.nextHandler = handler2
        handler2.nextHandler = handler3

        //构造3个请求者对象
        val request1 = Request1("Request1")
        val request2 = Request2("Request2")
        val request3 = Request3("Request3")

        //每次都从链式的手端发起请求
        handler1.handleRequest(request1)
        handler1.handleRequest(request2)
        handler1.handleRequest(request3)

    }
}

对应打印结果如下:

Handler1 handle request:1
Handler2 handle request:2
Handler3 handle request:3

实现示例

这里举个简单的栗子,忽略UML图中的请求者角色,比如你是公司员工需要请假,3天以内的主管可以直接审批通过,大于3天小于7天的部门经理可以审批通过,如果7天以上的需要董事长才可以审批通过,下面我们就针对这个例子使用责任链模式来实现;

  • 定义抽象领导者类,Leader
/**
 * 抽象领导者
 */
abstract class Leader {
    var nextLeader: Leader? = null


    fun handleRequest(days: Int) {
        if (handleDays(days)) {
            handle(days)
        } else {
            nextLeader?.handleRequest(days)
        }
    }

    /**
     * 当前领导是否可以审批请假天数
     */
    protected abstract fun handleDays(days: Int): Boolean

    /**
     * 具体审批操作
     */
    protected abstract fun handle(days: Int)
}
  • 部门主管处理者,DirectorLeader
/**
 * 部门主管处理者
 */
class DirectorLeader : Leader() {

    override fun handleDays(days: Int): Boolean {
        return days <= 3
    }

    override fun handle(days: Int) {
        println("部门主管审批${days}天假期通过")
    }
}
  • 经理处理者,ManagerLeader
/**
 * 经理处理者
 */
class ManagerLeader : Leader() {

    override fun handleDays(days: Int): Boolean {
        return days <= 7
    }

    override fun handle(days: Int) {
        println("经理审批${days}天假期通过")
    }
}
  • 老板处理者,BossLeader
/**
 * 老板处理者
 */
class BossLeader : Leader() {

    override fun handleDays(days: Int): Boolean {
        return true
    }

    override fun handle(days: Int) {
        println("老板审批${days}天假期通过")
    }
}
  • 测试类
object Test {

    @JvmStatic
    fun main(args: Array<String>) {
        //构造各个领导
        val directorLeader = DirectorLeader()
        val managerLeader = ManagerLeader()
        val bossLeader = BossLeader()
        directorLeader.nextLeader = managerLeader
        managerLeader.nextLeader = bossLeader
        directorLeader.handleRequest(2) //打印结果:部门主管审批2天假期通过
        directorLeader.handleRequest(6) //打印结果:经理审批6天假期通过
        directorLeader.handleRequest(10) //打印结果:老板审批10天假期通过
    }
}

当然,如果部门主管和经理都不在的时候,我们可以直接提交给老板进行处理,这就是责任链模式的灵活之处!

Android源码中的责任链模式

  • View事件分发流程,这里不再过多赘述,大家肯定都比较清楚;
  • OkHttp发起网络请求,通过责任链模式一层一层将请求进行封装并发起最终请求;

总结

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

缺点:
需要对链中请求处理者进行遍历,如果处理者太多,会影响性能。

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值