美文网首页kotlin
kotlin 函数级代理模式

kotlin 函数级代理模式

作者: capcNote | 来源:发表于2018-09-20 13:07 被阅读0次

    最近看到一种很有意思的类写法:

    class ExampleProxy(private val method: (String) -> Unit) : (String) -> Unit {
        override fun invoke(param: String) {
            println("proxy do something...")
            method(param)
        }
    }
    
    

    定义了一个ExampleProxy类,返回类型是一个函数类型定义(String) -> Unit。类内重载了invoke操作符,参数类型必需和类返回的函数类型定义中的参数类型是一致的(有点绕)。

    FunctionX

    注意到,如果类返回类型是函数定义的话,invode方法是必需重载的。可以看到如果注释掉invoke方法,IDE会提示如下:

    根据提示可以看出,重载的是kotlin包内Function1接口的invode方法,所以我之前的描述是有问题的:ExampleProxy并不是返回函数定义(String) -> Unit,而是实现了接口Function1。换一个角度看,kotlin内形如(R,..)->T的函数类型等价于FunctionXR,..参数数量即为X 点进Functions.kt可以看到最多支持到22个参数函数类型定义,只是写法...确实很简单粗暴...
    实现FunctionX的类可以做什么?

    回到正题,前文实现了Function1ExampleProxy类,其每个实例对象即代表一个函数引用。由此我们可以在类构造函数内传入相同函数类型定义的函数引用,实现函数层面的动态代理。

    函数级代理

    定义一个类A

    class A {
        fun printInfo(s: String) {
            println("I'm $s")
        }
    }
    

    以被代理函数printInfo的引用作为构造参数实例化出一个ExampleProxy类的对象printInfoProxyprintInfoProxy("abc")方式的调用效果等同于printInfoProxy.invoke("abc")。执行main方法:

    fun main(args: Array<String>) {
        val printInfoProxy = ExampleProxy(A()::printInfo)
        printInfoProxy("abc")
    }
    

    打印结果:

    proxy do something...
    I'm abc
    

    可以看到,由此实现了代理的效果。
    实际上这是一种形式受限的动态代理,ExampleProxy只可以代理(String) -> Unit类型的函数。

    相关文章

      网友评论

        本文标题:kotlin 函数级代理模式

        本文链接:https://www.haomeiwen.com/subject/dargnftx.html