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

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

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

kotlin 复制代码
interface Component {
	fun method1(): IntArray
	fun method2(a: Int)
	fun method3(a: Int, str: String)
}

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

kotlin 复制代码
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)
}

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

kotlin 复制代码
class Decorator(private val component: Component): Component by component

  这两段代码功能一致。

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

kotlin 复制代码
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)
}

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

kotlin 复制代码
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()
	}
}

  运行结果:

相关推荐
云和数据.ChenGuang1 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
金銀銅鐵1 小时前
同一个 Hello World,Kotlin 和 Java 在字节码层面差在哪
jvm·后端·kotlin
蜗牛一步步往上爬4 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y6 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
冻柠檬飞冰走茶9 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
心若自由何处是束缚9 小时前
适配器模式:从原理到实战的完整指南
设计模式·适配器模式
FRing039 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊9 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆67510 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩11 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常