前言

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

摘自百度百科《装饰器模式》


Kotlin中的装饰器模式

委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。
Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。
在装饰器模式中,Kotlin的简化方案可以使用类委托方式简化代码。
类委托
类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的。
以下实例中派生类 Derived 继承了接口 Base 所有方法,并且委托一个传入的 Base 类的对象来执行这些方法。

// 创建接口
interface Base {   
    fun print()
}

// 实现此接口的被委托的类
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

// 通过关键字 by 建立委托类
class Derived(b: Base) : Base by b

fun main(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).print() // 输出 10
}

在 Derived 声明中,by 子句表示,将 b 保存在 Derived 的对象实例内部,而且编译器将会生成继承自 Base 接口的所有方法, 并将调用转发给 b。

Show me code

interface CoffeeMachine {
    fun makeSmallCoffee()
    fun makeLargeCoffee()
}

class NormalCoffeeMachine : CoffeeMachine {
    override fun makeSmallCoffee() = println("Normal: Making small coffee")

    override fun makeLargeCoffee() = println("Normal: Making large coffee")
}

//Decorator:
class EnhancedCoffeeMachine(val coffeeMachine: CoffeeMachine) : CoffeeMachine by coffeeMachine {

    // overriding behaviour
    override fun makeLargeCoffee() {
        println("Enhanced: Making large coffee")
        coffeeMachine.makeLargeCoffee()
    }

    // extended behaviour
    fun makeCoffeeWithMilk() {
        println("Enhanced: Making coffee with milk")
        coffeeMachine.makeSmallCoffee()
        println("Enhanced: Adding milk")
    }
}

调用代码:

val normalMachine = NormalCoffeeMachine()
val enhancedMachine = EnhancedCoffeeMachine(normalMachine)

// non-overridden behaviour
enhancedMachine.makeSmallCoffee()
// overriding behaviour
enhancedMachine.makeLargeCoffee()
// extended behaviour
enhancedMachine.makeCoffeeWithMilk()