手把手教你从0开始写一个责任链
程序员文章站
2024-02-18 18:17:46
...
在java设计模式中,责任链模式算是比较常见的设计模式了,运用链式调用,可以在多个节点依次对数据进行处理。优势就是可以将节点的创建和调用进行分离,降低代码之间的耦合度。
本文手把手教你用kotlin从0到1写一个责任链(总共3个节点),每个节点加入拦截器interceptor,监听器listener,并且支持每个节点和整个责任链的参数传递。
话不多说,直接上代码
拦截器
abstract class Interceptor {
private var listener: Listener? = null
fun attach(listener: Listener?, args: Array<out Any?>?) {
this.listener = listener
initWithArgs(args)
}
fun onStart() {
listener?.onStart()
}
fun onEnd() {
listener?.onEnd()
}
abstract fun <T> intercept(chainNode: Chain<T>, input: T)
open fun initWithArgs(args: Array<out Any?>?) {
}
}
三个子类分别如下:
class NodeOneInterceptor : Interceptor() {
override fun initWithArgs(args: Array<out Any?>?) {
super.initWithArgs(args)
Log.e(TAG, args?.get(0)?.toString()!!)
}
override fun <T> intercept(chainNode: Chain<T>, input: T) {
onStart()
if (input is String) {
Log.e(TAG, input)
}
Log.e(TAG, "********NodeOneInterceptor")
chainNode.proceed(input)
}
}
class NodeTwoInterceptor : Interceptor() {
override fun initWithArgs(args: Array<out Any?>?) {
super.initWithArgs(args)
Log.e(TAG, args?.get(0)?.toString()!!)
}
override fun <T> intercept(chainNode: Chain<T>, input: T) {
onStart()
if (input is String) {
Log.e(TAG, input)
}
Log.e(TAG, "********NodeTwoInterceptor")
chainNode.proceed(input)
}
}
class NodeThreeInterceptor : Interceptor() {
override fun initWithArgs(args: Array<out Any?>?) {
super.initWithArgs(args)
Log.e(TAG, args?.get(0)?.toString()!!)
}
override fun <T> intercept(chainNode: Chain<T>, input: T) {
onStart()
if (input is String) {
Log.e(TAG, input)
}
Log.e(TAG, "********NodeThreeInterceptor")
chainNode.proceed(input)
}
}
监听器
interface Listener {
fun onStart()
fun onEnd()
}
我们针对每个节点同样创建一个监听器:
class NodeOneListener : Listener {
override fun onStart() {
Log.e(Constants.TAG, "********NodeOneListener_onStart")
}
override fun onEnd() {
Log.e(Constants.TAG, "********NodeOneListener_onEnd")
}
}
class NodeTwoListener : Listener {
override fun onStart() {
Log.e(Constants.TAG, "********NodeTwoListener_onStart")
}
override fun onEnd() {
Log.e(Constants.TAG, "********NodeTwoListener_onEnd")
}
}
class NodeThreeListener : Listener {
override fun onStart() {
Log.e(Constants.TAG, "********NodeThreeListener_onStart")
}
override fun onEnd() {
Log.e(Constants.TAG, "********NodeThreeListener_onEnd")
}
}
最后我们在main里面进行注册和调用:
fun main() {
val chainNode = buildPipeLine<String>()
chainNode.proceed("chain process start")
}
private fun <T> buildPipeLine(): Chain<T> {
// 节点的创建和注册
val pepes = mutableListOf<Pipe>()
pepes.add(obtain().interceptor(NodeOneInterceptor::class.java).listener(NodeOneListener()).args("aaa").build())
pepes.add(obtain().interceptor(NodeTwoInterceptor::class.java).listener(NodeTwoListener()).args("bbb").build())
pepes.add(obtain().interceptor(NodeThreeInterceptor::class.java).listener(NodeThreeListener()).args("ccc").build())
return assemble(pepes)
}
// 组装责任链Chain
private fun <T> assemble(pepes: MutableList<Pipe>): Chain<T> {
return RealProceedChain(pepes, 0, null)
}
其中Pipe和RealProceedChain的定义分别如下:
// 建造者模式的运用
class Pipe private constructor(builder: Builder){
val mInterceptorClz: Class<out Interceptor>?
val mListener: Listener?
val mArgs: Array<out Any?>?
init {
mInterceptorClz = builder.mInterceptorClz
mListener = builder.mListener
mArgs = builder.mArgs
}
class Builder private constructor() {
var mInterceptorClz: Class<out Interceptor>? = null
var mListener: Listener? = null
var mArgs: Array<out Any?>? = null
companion object {
@JvmStatic
fun obtain(): Builder = Builder()
}
fun interceptor(clazz: Class<out Interceptor>): Builder {
mInterceptorClz = clazz
return this
}
fun listener(listener: Listener): Builder {
mListener = listener
return this
}
fun args(vararg args: Any?): Builder {
mArgs = args
return this
}
fun build(): Pipe {
return Pipe(this)
}
}
}
class RealProceedChain<T>(private val pipes: List<Pipe>, private var index: Int, private val preInterceptor: Interceptor?) : Chain<T> {
override fun proceed(input: T) {
preInterceptor?.let {
preInterceptor.onEnd()
}
if (index >= pipes.size) {
return
}
val pipe = pipes[index]
var interceptor: Interceptor? = null
try {
interceptor = pipe.mInterceptorClz?.newInstance()
} catch(e: Throwable) {
Log.e(TAG, e.message!!)
}
interceptor?.attach(pipe.mListener, pipe.mArgs)
val next = RealProceedChain<T>(pipes, ++index, interceptor)
interceptor?.intercept(next, input)
}
}
interface Chain<T> {
// 支持整个责任链的数据传递
fun proceed(input: T)
}
调用输出
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: aaa
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeOneListener_onStart
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: chain process start
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeOneInterceptor
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeOneListener_onEnd
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: bbb
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeTwoListener_onStart
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: chain process start
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeTwoInterceptor
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeTwoListener_onEnd
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ccc
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeThreeListener_onStart
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: chain process start
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeThreeInterceptor
2021-07-16 21:08:25.894 20835-20835/com.example.kotlin E/gecko_log_tag: ********NodeThreeListener_onEnd
可以看到责任链模式的写法是先创建每个节点进行注册,然后从首节点开始调用(此时index == 0)。在调用当前节点的intercepter方法时,传入下个节点的引用,然后调用下个节点,依此类推,完成整个责任链的遍历。
以上示例完成了基本责任链的编写,在实际工作中还会加入多线程,异常捕获等其他功能,每个拦截器中的代码也会根据实际情况复杂很多,但基本原理都类似。
上一篇: 获取url后面的参数
下一篇: 微信授权