我有一个特性,它定义了一个没有参数的抽象方法。我想阻止实现者用val
覆盖它,因此每次需要它时都会调用该方法。例如。
sealed trait Downloader extends Loader {
def username: String
def password: String
def nonceProvider: NonceProvider
def request: Request
def download = {
val client = new Client
client execute request
}
}
这是用于下载某些资源的特征。现在有人可以编写以下不良实现:
case class DownloaderWithServiceDefinition(
override val username: String,
override val password: String,
override val nonceProvider: NonceProvider
serviceDefinition: ServiceDefinition) extends Downloader {
override val request = ServiceDefinitionRequest(serviceDefinition, username, password, nonceProvider.generateNonce())
}
在此实现中,request
在构造期间被赋值,而不是像方法一样,因此连续请求将具有相同的nonce值,这显然不是意图。我可以阻止这个吗?
答案 0 :(得分:0)
您不希望将其作为一般语言功能。假设特征需要 SOME 正确类型的request
的有效实现,并对该要求进行编码。但是,一个特征不能对此要求的实施细节做出任何假设/要求。
因此,实施者可以自由地使用def,val,var或者甚至是懒惰的val,因为它具有比特征更多的知识。如果正确的实现与您有关,那么避免错误的负担确实存在于实现本身中。
您可以将定义更改为def request(): Request
或def request: () => Request
,以使意图更清晰,并记录您需要的合同(实际的java / scala doc帮助)。
甚至可能是请求本身(如果仅用作 方式 >来获取nonce),根本不应该在特征中,因为它是一个实现详情。我会收集而不是Downloader
根本不会有一个Request
,但是根据需要制作许多,所以你可能会有一种气味,你应该以不同的方式构建你的OO设计。