eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Kotlinでinterface定義モジュールと実装モジュールを分離した上で実装を隠蔽する

やりたいこと

  • interface定義と、その実装をなるべくキレイに切り分けたい

インターフェース定義用モジュール

// ":interface-module" に定義を書いていく...
interface AuthService {
  fun login(id: String, password: String)
}

実装用モジュール

// ":impl-module" に実装を書いていく...
internal class AuthServiceImpl {
   override fun login(id: String, password: String) {
       // ログイン処理する....
   }
}

コレの問題点

  • AuthServiceImplがinternalなので、他のモジュールから見えない
  • けれどAuthServiceImplをモジュールの外に開放したくない(後で入替えたりとかやりやすいように)

解決

  • interface側にcompanion objectを入れておく

interface定義を修正

// companionだけ書いておく
interface AuthService {
  fun login(id: String, password: String)

  companion object
}

実装用モジュールにExtensionも定義

// ":impl-module" に実装を書いていく...
internal class AuthServiceImpl {
   override fun login(id: String, password: String) {
       // ログイン処理する....
   }
}

// CompanionのExtensionとしてインスタンス生成メソッドを生やす
// これはinternalにしない。
// 利用側からは `AuthService.newInstance()` と呼ぶことができる
fun AuthService.Companion.newInstance() {
    return AuthServiceImpl()
}