持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
Android中的责任链模式
责任链模式又叫拦截器模式,在Android源码与第三方库都有广泛的应用。
比如OkHttp的拦截器模式,比如View事件的分发,ViewGroup事件投递的递归调用就类似于一条责任链,一旦其寻找到责任者,那么将由责任者持有并消费掉该次事件,具体体现在View的onTouchEvent方法中返回值的设置,如果返回false,那么意味着当前的View不会是该次的责任人,将不会对其持有;如果返回true,此时View会持有该事件并不再向外传递。
责任链模式是指,当一个请求经过一个对象,就询问当前对象是否进行处理和拦截,判断是否可以往下一个对象传递,这样形成一个链,每一个对象都有机会处理改请求。
我们定义一个拦截请求,定义一个拦截器处理请求,再定义每一个拦截对象
1.拦截器请求接口
public abstract class InterceptChain<T> {
public InterceptChain next;
public void intercept(T data) {
if (next != null) {
next.intercept(data);
}
}
}
2.拦截器处理器
public class InterceptChainHandler<T> {
InterceptChain _interceptFirst;
public void add(InterceptChain interceptChain) {
if (_interceptFirst == null) {
_interceptFirst = interceptChain;
return;
}
InterceptChain node = _interceptFirst;
while (true) {
if (node.next == null) {
node.next = interceptChain;
break;
}
node = node.next;
}
}
public void intercept(T data) {
_interceptFirst.intercept(data);
}
}
3.通过对象来判断是否需要拦截
public class DialogPass {
public String msg;
public int passType;
}
4.定义每一个拦截对象,这里来5个
class OneIntercept : InterceptChain<DialogPass>() {
override fun intercept(data: DialogPass?) {
if (data != null) {
val interceptData = "当前的Data1:${data.msg}"
YYLogUtils.w(interceptData)
//判断当前是否弹窗
if (data.passType == 1) {
FangIOSDialog(mActivity).apply {
setTitle("测试弹框1")
setMessage("弹框的内容")
setNegativeButton("No") {
dismiss()
}
setPositiveButton("Yes") {
dismiss()
//判断逻辑,是否需要弹出下一个弹窗
//如果需要弹出下一个弹窗 设置下一个弹窗的passType
data.passType = 2
super.intercept(data)
}
show()
}
}else{
super.intercept(data)
}
} else {
super.intercept(data)
}
}
}
class TwoIntercept : InterceptChain<DialogPass>() {
override fun intercept(data: DialogPass?) {
if (data != null) {
val interceptData = "当前的Data2:${data.msg}"
YYLogUtils.w(interceptData)
//判断当前是否弹窗
if (data.passType == 2) {
FangIOSDialog(mActivity).apply {
setTitle("测试弹框2")
setMessage("弹框的内容")
setNegativeButton("No") {
dismiss()
}
setPositiveButton("Yes") {
dismiss()
//判断逻辑,是否需要弹出下一个弹窗
//如果需要弹出下一个弹窗 设置下一个弹窗的passType
data.passType = 3
super.intercept(data)
}
show()
}
}else{
super.intercept(data)
}
} else {
super.intercept(data)
}
}
}
class ThreeIntercept : InterceptChain<DialogPass>() {
override fun intercept(data: DialogPass?) {
if (data != null) {
val interceptData = "当前的Data3:${data.msg}"
YYLogUtils.w(interceptData)
//判断当前是否弹窗
if (data.passType == 3) {
FangIOSDialog(mActivity).apply {
setTitle("测试弹框3")
setMessage("弹框的内容")
setNegativeButton("No") {
dismiss()
}
setPositiveButton("Yes") {
dismiss()
//判断逻辑,是否需要弹出下一个弹窗
//如果需要弹出下一个弹窗 设置下一个弹窗的passType
data.passType = 5
super.intercept(data)
}
show()
}
}else{
super.intercept(data)
}
} else {
super.intercept(data)
}
}
}
class FourIntercept : InterceptChain<DialogPass>() {
override fun intercept(data: DialogPass?) {
if (data != null) {
val interceptData = "当前的Data4:${data.msg}"
YYLogUtils.w(interceptData)
//判断当前是否弹窗
if (data.passType == 4) {
FangIOSDialog(mActivity).apply {
setTitle("测试弹框4")
setMessage("弹框的内容")
setNegativeButton("No") {
dismiss()
}
setPositiveButton("Yes") {
dismiss()
//判断逻辑,是否需要弹出下一个弹窗
//如果需要弹出下一个弹窗 设置下一个弹窗的passType
data.passType = 5
super.intercept(data)
}
show()
}
}else{
super.intercept(data)
}
} else {
super.intercept(data)
}
}
}
class FiveIntercept : InterceptChain<DialogPass>() {
override fun intercept(data: DialogPass?) {
if (data != null) {
val interceptData = "当前的Data5:${data.msg}"
YYLogUtils.w(interceptData)
//判断当前是否弹窗
if (data.passType == 5) {
FangIOSDialog(mActivity).apply {
setTitle("测试弹框5")
setMessage("弹框的内容")
setNegativeButton("No") {
dismiss()
}
setPositiveButton("Yes") {
dismiss()
//判断逻辑,是否需要弹出下一个弹窗
//如果需要弹出下一个弹窗 设置下一个弹窗的passType
}
show()
}
}else{
super.intercept(data)
}
} else {
super.intercept(data)
}
}
测试使用
//测试拦截器模式
val intercepts = InterceptChainHandler<DialogPass>()
intercepts.add(OneIntercept())
intercepts.add(TwoIntercept())
intercepts.add(ThreeIntercept())
intercepts.add(FourIntercept())
intercepts.add(FiveIntercept())
val dialogPass = DialogPass().apply {
msg = "测试弹窗流程"
passType = 1
}
intercepts.intercept(dialogPass)
总结
责任链设计模式并没有固定的写法,可以有不同的实现,中心思想都是一样的,就是从一个起点发起请求,然后沿着任务链依次传递给每一个节点上的对象,直到有一个节点处理这个请求为止,也是我们再平常开发中常用的设计模式之一了。
优点:
可以对请求者和处理者的关系解耦,提高代码的灵活性。
缺点:
每次都需要对链中请求处理者遍历,如果处理者太多那么遍历必定会影响性能,特别是在一些递归调用者中,要慎用。
此篇只是展示责任链模式的概念与基本使用,关于弹窗的拦截后期会单独出一期实战的文章。