欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手把手教你从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方法时,传入下个节点的引用,然后调用下个节点,依此类推,完成整个责任链的遍历。

以上示例完成了基本责任链的编写,在实际工作中还会加入多线程,异常捕获等其他功能,每个拦截器中的代码也会根据实际情况复杂很多,但基本原理都类似。