Motivation: We want to add responsibilities to an object dynamically at runtime, rather than statically through inheritance. Subclassing every combination of features would lead to a combinatorial explosion of classes.

Intent: Attach additional responsibilities to an object dynamically, providing a flexible alternative to subclassing.

Decorators are seen a lot in Python and Java and these wrap components and forward calls to a method, adding behaviour before or after. These can be stacked. Each decorator stays focused on a single responsibility.

interface Beverage {
    fun cost(): Double
    fun description(): String
}
 
class Coffee : Beverage {
    override fun cost() = 1.5
    override fun description() = "Coffee"
}
 
class Tea : Beverage {
    override fun cost() = 1.0
    override fun description() = "Tea"
}
 
abstract class BeverageDecorator(private val beverage: Beverage) : Beverage {
    abstract override fun cost(): Double
    abstract override fun description(): String
}
 
class MilkDecorator(beverage: Beverage) : BeverageDecorator(beverage) {
    override fun cost() = super.cost() + 0.5
    override fun description() = super.description() + " + milk"
}
 
class SugarDecorator(beverage: Beverage) : BeverageDecorator(beverage) {
    override fun cost() = super.cost() + 0.2
    override fun description() = super.description() + " + sugar"
}
 
// Decorators can be composed freely
val order: Beverage = MilkDecorator(SugarDecorator(Coffee()))
// -> Coffee + sugar + milk