Kotlin には Class Delegation という機能が言語レベルで用意されています。
interface MyInterface {
fun hoge(): String
}
class Impl : MyInterface {
override fun hoge() : String = "implemented!!"
}
class Delegation : MyInterface by Impl()
val i = Delegation()
println("${i.hoge()}") // implemented!!
コードサンプルを書くとなんてことが無い機能で、 interface の実装をクラス定義の際に別のインスタンスへ委譲できるようになります。確かに、多重継承が許されている Kotlin では、この機能を利用することで同じ実装が何度も登場するのを防ぐことができる・・・そんな気がします。
とは言え、具体的にどこで使用するべきなのか、となると良いサンプルが思いつきませんが、例えばテストを書くときに、モックオブジェクトの生成を Class Delegation を使うことで簡単にできます。
無名オブジェクトを作って、必要な部分のみをオーバーライドする
ユニットテストを書くときモックを作るパターンはよくあります。モックを作るための仕組みとして mockito 等のライブラリがあります。しかし、 Kotlin ではライブラリに依存することなく Class Delegation を利用することでモックの生成が可能になります。
impl.kt
interface User {
val name: String
val id: Long
val address: Address
}
fun testTargetFunction(u: User) : String = u.name.toUpperCase()
上記のような interface User
と実装 testTargetFunction
があった物として。
test.kt
fun loadUserByJSON(json: String) : User = { ... }
fun test() {
val user = object: User by loadUserByJSON(json) {
override val name: String = "name"
}
val expected = "NAME"
val actual = testTargetFunction(user)
assert(expected == actual)
}
このように、テストのときに必要なメソッドのみをオーバーライドした無名オブジェクトを作ることができます。
WEBサービスと連携をするアプリなんかを作るときに、テスト用データを利用してテストをするときに便利だと思います。
便利な Kotlin を使ってスマートにテストを書いていきましょう。