cake pattern

導入

まずは概念からまとめておきたい。

Scalaにおける最適なDependency Injectionの方法を考察する 〜なぜドワンゴアカウントシステムの生産性は高いのか〜 #Scala - Qiita

下記はCake PatternによるDIを実装しないパターン。 UserServiceUserRepositoryのみでなくUserRepositoryImplへ依存しているため、UserRepositoryImplの変更がUserServiceへ影響してしまう。

trait UserRepository {
  // 略
}

object UserRepositoryImpl extends UserRepository {
  // 略
}

object UserService {
  val userRepository: UserRepository = UserRepositoryImpl // ← ここでImplを参照しているのが問題
  // 略
}

下記はCake PatterによるDIを実装したパターン。 独自解釈すると、、 UserService: サービス UserRepository: 外部実装の抽象 UserRepositoryImpl: 外部実装 があったのに対し、下記を追加実装し、結合箇所は抽象層のみとした。 UserService(trait): サービスの抽象 UserRepositoryComponent: 「外部実装の抽象」の抽象 UserRepositoryComponentImpl: 「外部実装の抽象化」の抽象

trait UserRepositoryComponent {
  val userRepository: UserRepository

  trait UserRepository {
    // 略
  }
}

trait UserRepositoryComponentImpl extends UserRepositoryComponent {
  val userRepository = UserRepositoryImpl

  object UserRepositoryImpl extends UserRepository {
    // 略
  }
}

trait UserService {
  this: UserRepositoryComponent =>
  // 略
}

object UserService extends UserService with UserRepositoryComponentImpl

Minimal Cake Pattern 再考 #テスト - Qiita

Rustでの実践

RustのDI | κeenのHappy Hacκing Blog Cake PatternでDIしてみた | blog.ojisan.io Rust で DI | blog.ojisan.io