私たちはいくつかのタイプのリソースを持っており、リソースが健全かどうかをチェックするメソッドを作りたかったのです。リソースの種類は、我々は、標準的なサブクラス化を使用したくなかった非常に不均一であることを考えると、私たちは型クラスを使用することにしました:指定されたリソースが生きているかどうかを確認することができるように型のスカラ型パターンと共分散
trait CanHealthCheck[T] {
def isHealthy(t: T): Boolean
}
我々はまた、ユーティリティメソッドを持っています/健全かどうか
object LivenessChecker {
def isAlive[T](t: T)(implicit canHealthCheck: CanHealthCheck[T]): Boolean = {
canHealthCheck.isHealthy(t)
}
}
データにアクセスするためのリポジトリレイヤーがあります。私たちは、与えられた抽象リポジトリが「健康チェック可能」でなければならないという考えを表現するが、形質を実装するサブクラスに実装の詳細を残したいと思います:
trait UserRepository {
def findSomeUser(): User = ???
implicit def isHealthCheckable: CanHealthCheck[UserRepository]
}
我々は特定してUserRepositoryサブクラス化したいときに問題が発生しましたCanHealthCheckは、タイプのTにのの共変量ではありません。
class DbUserRepository extends UserRepository {
def ping: Boolean = ???
override implicit val isHealthCheckable: CanHealthCheck[UserRepository] =
new CanHealthCheck[DbUserRepository] {
def isHealthy(db: DbUserRepository) = db.ping
}
}
そして、これはリポジトリが生きているかどうかを確認しようとしているときに、抽象リポジトリに作用するいくつかのダミー関数の一例です:アイデアは我々のアプリケーションは、UserRepositoryを使用していることである
def someDummyFunction(userRepository: UserRepository) = {
if(LivenessChecker.isAlive(userRepository)) // This won't compile
userRepository.findSomeUser()
}
リポジトリが生存しているかどうかを確認することはできません。リポジトリ抽象化レイヤーを引き続き使用して、与えられた(抽象的な)リポジトリが生存しているかどうかを確認する方法はありますか? typeclassパターンはここで使用する正しいパターンですか?
この問題の解決方法はわかりません。私たちは 'CanHealthCheck [UserRepository]'が必要ですが、あなたの例では 'U <:UserRepository'で' CanHealthCheck [U] 'を取得します。 CanHealthCheckが** Tの共変**ではないことを考えれば、これはうまくいきません。 –
あなたの質問に「CanHealthCheckはタイプTの共変ではありません。私はコードをコンパイルする方法を参照する答えを残しておきます...今のところ: - \ –