우리는 여러 가지 유형의 리소스를 가지고 있으며 리소스가 정상적인 지 여부를 확인하는 방법을 만들고 싶습니다. 자원의 종류는 우리가 표준 서브 클래스를 사용하지 않은 매우 이질적인 것을 감안할 때 우리는 typeclass를 사용하기로 결정 : 주어진 자원이 살아 있는지 확인 할 수스칼라 typeclass 패턴 및 공분산
trait CanHealthCheck[T] {
def isHealthy(t: T): Boolean
}
우리는 또한 유틸리티 메소드가/건강한가/아니오
object LivenessChecker {
def isAlive[T](t: T)(implicit canHealthCheck: CanHealthCheck[T]): Boolean = {
canHealthCheck.isHealthy(t)
}
}
데이터에 액세스하기위한 저장소 계층이 있습니다. 우리가 특정과 UserRepository 하위 클래스로 할 때
trait UserRepository {
def findSomeUser(): User = ???
implicit def isHealthCheckable: CanHealthCheck[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
}
}
그리고 이것은 저장소가 살아 있는지 확인하는 동안 추상 저장소에 작용 몇 가지 더미 기능의 예는 다음과 같습니다
이def someDummyFunction(userRepository: UserRepository) = {
if(LivenessChecker.isAlive(userRepository)) // This won't compile
userRepository.findSomeUser()
}
아이디어는 우리의 응용 프로그램이 UserRepository를 사용하는 것을 특성이 아니며, 따라서 저장소가 살아 있는지 여부를 확인할 수 없습니다. 저장소 추상화 계층을 계속 사용하고 주어진 (추상) 저장소가 살아 있는지 확인할 수있는 방법은 무엇입니까? typeclass 패턴이 여기에서 사용할 올바른 패턴입니까?
이 문제가 어떻게 해결되는지는 알 수 없습니다.우리는'CanHealthCheck [UserRepository]'가 필요하지만, 당신의 예제에서는'U <: UserRepository'를 가진'CanHealthCheck [U]'를 얻습니다. CanHealthCheck가 T에서 ** 공변 **이 아니므로, 작동하지 않을 것입니다. –
죄송합니다. CanHealthCheck는 T 형에서 공변이지 않습니다. "라는 질문에 빠졌습니다. 나는 코드를 컴파일하는 법에 대한 참조로 답을 남겨 둘 것이다. 지금은 - \ –