0

初めてケーキ柄を使ってみました。

それがどのように機能するかはある程度理解していますが、すでに混合されている特性などを混合することが可能かどうかを知りたい.

私が望むのは、ケーキ パターンを使用してグローバル アプリケーションを構築することです。そして、リポジトリレベルを除いて同じアプリケーションの別のバージョンが必要です。

次のようなことは可能ですか:

  trait application extends DefaultUserServiceComponent with MongoUserRepositoryComponent

  object realApplication extends application
  object fakeApplication extends FakeUserRepositoryComponent with application

つまり、偽のリポジトリを使用して偽のアプリケーションを構築するときに、既に構築されたアプリケーションを再利用するということですか?

4

1 に答える 1

2

簡単な答え: いいえ。競合するメンバーを継承することになります。次のコード スニペットを参照してください。

trait Repository {def authenticate(username: String, password: String): String}

trait UserServiceComponent {self: UserRepositoryComponent =>
  val userService: UserService = new UserService
  class UserService {
    def authenticate(username: String, password: String): String =
      repository.authenticate(username, password)
  }
}

trait UserRepositoryComponent {
  def repository: Repository
}

trait MongoUserRepositoryComponent extends UserRepositoryComponent {
  val repository: Repository =
    new Repository {def authenticate(username: String, password: String) = "MongoAuthed"}
}

trait MockUserRepositoryComponent extends UserRepositoryComponent {
  val repository: Repository =
    new Repository {def authenticate(username: String, password: String) = "MockAuthed"}
}

trait Application extends UserServiceComponent with MongoUserRepositoryComponent

object RealApplication extends Application
// The following will be an error: "object FakeApplication inherits conflicting members:"
object FakeApplication extends Application with MockUserRepositoryComponent

代わりに、目的の動作を実現するには、Application を次のように定義します。

trait Application extends UserServiceComponent {self: UserRepositoryComponent =>}
object RealApplication extends Application with MongoUserRepositoryComponent
object FakeApplication extends Application with MockUserRepositoryComponent

OPで指定された階層を維持するには、コードを次のように変更する必要があります。

trait MongoUserRepositoryComponent extends UserRepositoryComponent {
  private val _repository = new Repository {def authenticate(username: String, password: String) = "MongoAuthed"}
  def repository: Repository = _repository
}

trait MockUserRepositoryComponent extends UserRepositoryComponent {
  private val _repository = new Repository {def authenticate(username: String, password: String) = "MockAuthed"}
  def repository: Repository = _repository
}

trait Application extends UserServiceComponent with MongoUserRepositoryComponent

object RealApplication extends Application
object FakeApplication extends Application with MockUserRepositoryComponent {
  override val repository: Repository = super[MockUserRepositoryComponent].repository
}

追加private val _repositoryの は、関数として定義repositoryして でオーバーライドとして使用できるようにするために必要FakeApplicationです。(super[type]オーバーライドの使用は関数でのみ機能します)。

EDIT : 最後に、cake パターンの目的は、私が提供した最後のコード スニペットのようにオーバーライドする必要のない階層を開発することです。実際には、この特性はApplicationまったく存在しないはずです。(2 番目のコード スニペットでは、名前を に変更するだけです)。RealApplicationFakeApplicationUserServiceComponentApplication

于 2013-01-09T21:43:42.940 に答える