Delegation Pattern
Kotlin supports easy implementation of the delegation pattern on the native level without any boilerplate code.
interface SoundBehavior { // 1
fun makeSound()
}
class ScreamBehavior(val n: String): SoundBehavior { // 2
override fun makeSound() = println("${n.uppercase()} !!!")
}
class RockAndRollBehavior(val n: String): SoundBehavior { // 2
override fun makeSound() = println("I'm The King of Rock 'N' Roll: $n")
}
// Tom Araya is the "singer" of Slayer
class TomAraya(n: String): SoundBehavior by ScreamBehavior(n) // 3
// You should know ;)
class ElvisPresley(n: String): SoundBehavior by RockAndRollBehavior(n) // 3
fun main() {
val tomAraya = TomAraya("Thrash Metal")
tomAraya.makeSound() // 4
val elvisPresley = ElvisPresley("Dancin' to the Jailhouse Rock.")
elvisPresley.makeSound()
}
- Defines the interface
SoundBehavior
with one method. - The classes
ScreamBehavior
andRockAndRollBehavior
implement the interface and contain their own implementations of the method. - The classes
TomAraya
andElvisPresley
also implement the interface, but not the method. Instead, they delegate the method calls to the responsible implementation. The delegate object is defined after theby
keyword. As you see, no boilerplate code is required. - When
makeSound()
is called ontomAraya
of typeTomAraya
orelvisPresley
of typeElvisPresley
, the call is delegated to the corresponding delegate object.