• 【kotlin】利用by关键字更加方便地实现装饰器模式


      关于kotlin中的by关键字的用法,kotlin官方文档属性委托这一节讲得很清楚。

      简单来说就是这样的,假设存在一个接口Component如下:

    interface Component {
    	fun method1(): IntArray
    	fun method2(a: Int)
    	fun method3(a: Int, str: String)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

      那么对于实现该接口的方法,可以这样:

    class Decorator(private val component: Component): Component {
    	override fun method1(): IntArray = component.method1()
    	override fun method2(a: Int) = component.method2(a)
    	override fun method3(a: Int, str: String) = component.method3(a, str)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

      但也可以通过by关键字更简单地实现:

    class Decorator(private val component: Component): Component by component
    
    • 1

      这两段代码功能一致。

      于是我们便能利用这一功能来更方便地实现装饰器模式,现在我们来实现三个装饰器类,分别对Component的三个方法进行装饰。

    interface Component {
    	fun method1(): IntArray
    	fun method2(a: Int)
    	fun method3(a: Int, str: String)
    }
    
    class Decorator1(
    	private val component: Component,
    	private inline val f0: ()->Unit = {},
    	private inline val f1: (arr: IntArray)->IntArray = {arr -> arr}
    ): Component by component {
    	override fun method1(): IntArray {
    		f0()
    		return f1(component.method1())
    	}
    //	相当于自动实现了
    //	override fun method2(a: Int) = component.method2(a)
    //	override fun method3(a: Int, str: String) = component.method3(a, str)
    }
    
    class Decorator2(
    	private val component: Component,
    	private inline val f0: (Int)->Unit = {},
    	private inline val f1: (Int)->Unit = {}
    ): Component by component {
    	override fun method2(a: Int) {
    		f0(a)
    		component.method2(a)
    		f1(a)
    	}
    //	override fun method1(): IntArray = component.method1()
    //	override fun method3(a: Int, str: String) = component.method3(a, str)
    }
    
    class Decorator3(
    	private val component: Component,
    	private inline val f0: (Int, String)->Unit = {_, _ -> },
    	private inline val f1: (Int, String)->Unit = {_, _ -> }
    ): Component by component {
    	override fun method3(a: Int, str: String) {
    		f0(a, str)
    		component.method3(a, str)
    		f1(a, str)
    	}
    //	override fun method1(): IntArray = component.method1()
    //	override fun method2(a: Int) = component.method2(a)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

      在主函数中调用这三个装饰器。

    fun main() {
    
    	val obj1 = object: Component{
    		override fun method1(): IntArray = IntArray(5){it * it}
    		override fun method2(a: Int) = println("a^2 is ${a * a}")
    		override fun method3(a: Int, str: String) = println("a is a, and str is \"$str\"")
    	}
    
    	val obj2 = object: Component{
    		override fun method1(): IntArray = IntArray(10){it}
    		override fun method2(a: Int) = println("a - 3 is ${a - 3}")
    		override fun method3(a: Int, str: String) = println("say \"$str\" to number a = $a")
    	}
    
    	val dcrt1: Component = Decorator1(obj1, {}){ arr ->
    		println("old arr is ${arr.contentToString()}")
    		return@Decorator1 IntArray(10) {it * it *it}
    	}
    
    	val dcrt2: Component = Decorator2(obj1){ a ->
    		println("a is $a")
    	}
    
    	val dcrt3: Component = Decorator3(obj2, { a, str ->
    		println("say \"$str\" to java $a times")
    	}, {a, str ->
    		println("and say \"$str\" to kotlin $a times")
    	})
    
    	val dcrt4: Component = Decorator2(Decorator3(obj2){ a, str ->
    		println("say \"$str\" to jetBrains $a times")
    	}){a ->
    		println("a + 3 is ${a + 3}")
    	}
    
    	display(dcrt1, 10, "Hello world!")
    	display(dcrt2, 15, "Hello kotlin!")
    	display(dcrt3, 20, "Hello, java!")
    	display(dcrt4, 25, "Hello, jetBrains!")
    
    }
    
    fun display(component: Component, a: Int, str: String) {
    	with(component) {
    		println("--------------------------------")
    		println(method1().contentToString())
    		method2(a)
    		method3(a, str)
    		println("--------------------------------")
    		println()
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

      运行结果:
    运行结果

  • 相关阅读:
    leetcode451:根据字符出现频率排序
    逍遥自在学C语言 | 位运算符^的高级用法
    值类型与引用类型的区别,以及string类型的解释
    尚品汇项目2
    RunnerGo UI自动化测试脚本如何配置
    管理多租户环境之PDB快照
    C++ Reference: Standard C++ Library reference: Containers: array: array: rbegin
    麦芽糖-聚乙二醇-甲氨蝶呤 MTX-PEG-maltose
    高级测试工程师必备技术:用Git版本控制自动化测试代码
    Linux-awk和printf
  • 原文地址:https://blog.csdn.net/qq_52247089/article/details/138190959