一 责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
二 适用场景
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 想在不明确指定接收者的情况下,像多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
三 UML结构图
- Handler 抽象处理角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。
- ConcreteHandler 具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。
进一步抽象:
对于请求来说,其形式是固定的,就是一个字符串,而判断一个节点上的对象是否能够处理该请求的标志,则是该字符串是否与之匹配。然而在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行抽象,使之对请求的处理规则也进行封装作为一个独立的对象。
四 代码实现
抽象请求,并一一实现:
abstract class AbstractRequest(var obj:String?) {
abstract fun getRequestLevel():Int
}
class Request1(obj: String?) : AbstractRequest(obj) {
override fun getRequestLevel(): Int {
return 1
}
}
class Request2(obj: String?) : AbstractRequest(obj) {
override fun getRequestLevel(): Int {
return 2
}
}
class Request3(obj: String?) : AbstractRequest(obj) {
override fun getRequestLevel(): Int {
return 3
}
}
抽象执行,并一一实现
abstract class AbstractHandler {
var nextHandler: AbstractHandler? = null
abstract fun getHandleLevel() : Int
abstract fun handle(request: AbstractRequest)
}
class Handler1 : AbstractHandler() {
override fun getHandleLevel(): Int {
return 1
}
override fun handle(request: AbstractRequest) {
if(request.getRequestLevel() == getHandleLevel()){
Log.d("handle1:","${request.obj}")
}
else{
nextHandler?.handle(request)
}
}
}
class Handler2 : AbstractHandler() {
override fun getHandleLevel(): Int {
return 2
}
override fun handle(request: AbstractRequest) {
if (request.getRequestLevel() == getHandleLevel()) {
Log.d("handle2:","${request.obj}")
} else {
nextHandler?.handle(request)
}
}
}
class Handler3 : AbstractHandler() {
override fun getHandleLevel(): Int {
return 3
}
override fun handle(request: AbstractRequest) {
if(request.getRequestLevel() == getHandleLevel()){
Log.d("handle3:","${request.obj}")
}
else{
nextHandler?.handle(request)
}
}
}
测试运行:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var handle1 = Handler1()
var handler2 = Handler2()
var handler3 = Handler3()
var request1 = Request1("我是request1,只有handler1才能处理我")
var request2 = Request2("我是request2,只有handler2才能处理我")
var request3 = Request3("我是request3,只有handler3才能处理我")
handle1.nextHandler = handler2
handler2.nextHandler = handler3
handle1.handle(request1)
handle1.handle(request2)
handle1.handle(request3)
}
结果:
handle1:: 我是request1,只有handler1才能处理我
handle2:: 我是request2,只有handler2才能处理我
handle3:: 我是request3,只有handler3才能处理我
五 优缺点
优点:对请求者和处理者关系解耦,提高代码的灵活性。
缺点:如果处理者太多,那么遍历必定会影响性能。
六 应用实例
-
Android 的触摸事件传递与分发机制(事件的传递转发机制)
-
利用有序广播实现责任链事件处理
Android种的BroastCast分为两种,一种时普通广播,另一种是有序广播。普通广播是异步的,发出时可以被所有的接收者收到。而有序广播是根据优先级一次传播的,直到有接收者将其终止或者所有接收者都不终止它。有序广播的这一特性与我们的责任链模式很相近,我们可以轻松地实现一种全局的责任链事件处理