前言
责任链模式是行为型
设计模式;
定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景:
- 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定;
- 在请求处理者不明确的情况下向多个对象中的一个提交一个请求;
- 需要动态指定一组对象处理请求;
UML类图:
AbstractHandler:
抽象处理者角色;
属性:
nextHandler:
保持对下一个节点处理者对象的引用;
方法:
handleRequest(AbstractRequest request):
处理请求;
getHandleLevel():
获取处理者对象的处理级别;
handle():
每个处理者对象的具体处理方式;
AbsRequest:
抽象请求者角色;
属性:
obj:
处理对象;
方法:
getContent():
获取具体的处理对象;
getRequestLevel():
获取请求级别;
ContrectHandler1
、ContrectHandler2
、ContrectHandler3
: 具体的处理者对象;
ContrectRequest1
、 ContrectRequest2
、ContrectRequest3
: 具体的请求者对象;
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,
Handler1
、Handler2
、Handler3
;
/**
* 处理者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,
Request1
、Request2
、Request3
/**
* 请求者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发起网络请求
,通过责任链模式一层一层将请求进行封装并发起最终请求;
总结
优点:
可以对请求者和处理者关系解耦,提高代码的灵活性。
缺点:
需要对链中请求处理者进行遍历,如果处理者太多,会影响性能。
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )