我可以阻止" def"被" val"覆盖?

时间:2015-07-27 14:13:46

标签: scala

我有一个特性,它定义了一个没有参数的抽象方法。我想阻止实现者用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值,这显然不是意图。我可以阻止这个吗?

1 个答案:

答案 0 :(得分:0)

您不希望将其作为一般语言功能。假设特征需要 SOME 正确类型的request的有效实现,并对该要求进行编码。但是,一个特征不能对此要求的实施细节做出任何假设/要求。

因此,实施者可以自由地使用def,val,var或者甚至是懒惰的val,因为它具有比特征更多的知识。如果正确的实现与您有关,那么避免错误的负担确实存在于实现本身中。

您可以将定义更改为def request(): Requestdef request: () => Request,以使意图更清晰,并记录您需要的合同(实际的java / scala doc帮助)。

甚至可能是请求本身(如果仅用作 方式 >来获取nonce),根本不应该在特征中,因为它是一个实现详情。我会收集而不是Downloader根本不会有一个Request,但是根据需要制作许多,所以你可能会有一种气味,你应该以不同的方式构建你的OO设计。