Search code examples
scalakotlindecorator

Decorate by Delegation (like kotlin) in Scala


In kotlin there is 'Decorate by Delegation' pattern. Is there a way to achieve it in an elegant way in Scala.

Here is a kotlin code example:

interface Doo{
    fun a(): Unit
    fun b(): Unit
}

class Goo:Doo {
    override fun a() {
        println("goo a")
    }

    override fun b() {
        println("goo b")
    }
}

class Moo(doo: Doo):Doo by doo{
    override fun b() {
        println("mooooooo")
    }
}

fun main() {
    val m = Moo(Goo())
    m.a();m.b()

}

Solution

  • In Scala 2, as far as I can tell, you cannot achieve this. It is however possible in Scala 3 with export:

    trait Foo {
      
      def a: Int
      
      def b: String
    }
    
    trait Bar {
      
      def a: Int
    }
    
    def decorateAsFoo(bar: Bar): Foo = new Foo {
      export bar._ // export all bar methods/values/types in this Foo impl
      
      override def b: String = "decorated"
    }
    
    
    decorateFoo(new Bar { override def a: Int = 10 })
    

    (See scastie)

    As you can see with export you don't even have to create a separate names class (though you could if you want to) nor you have to have any sort of subtyping relation between decorator and decoratee as long as the the result will have all the necessary definitions exported or implemented manually.

    In Scala 2 (to my knowledge), the best you can count on is conversion of one data-type into another data type with similar schema, via libraries like Chimney. I am not aware though of any library making such conversion between classes that store behavior.