【问题标题】:How to declare anonymous mixin using a type parameter in Scala如何在 Scala 中使用类型参数声明匿名 mixin
【发布时间】:2011-06-01 16:16:35
【问题描述】:

有人提出了一些与此问题有些相关的问题,但它们似乎不太合适。

我正在使用 Cake 模式将“存储”系统滑入生产代码中,并将存根存储系统滑入用于测试目的。这一切都很好,但是在原始类中实例化的类也需要混入这个存根存储系统。由于它隐藏在实现中,我无权访问它。

事情看起来像这样:

class Main { this: Storage =>
  ...
  val used = Used(...)
  ...
}

class Used { this: Storage =>
  ...
}

在测试“二手”时,我只需 new Used with StubStorage 就可以了。我曾经对Main 做同样的事情,但那是在它使用Used 之前。现在MainUsed 进行了简单的实例化,我遇到了这个问题。

我想这样尝试:

class Main[T <: Storage] { this: T =>
  ...
  val used = Used[T](...)
  ...
}

class Used[T <: Storage] { this: T =>
  ...
}
object Used {
  def apply[T <: Storage](...) = new Used(...) with T
}

但这当然行不通,因为编译器没有足够的信息来发现T。这有什么神奇的秘诀吗?我已经玩了一会儿,它似乎很麻烦,标准的 OO 注入方法实际上不那么麻烦,但我可能会遗漏一些东西。

我看过隐含的 Factory 概念,但我无法将其转化为适用于 mixins 的形状。

编辑:公开写出问题的清晰度令人惊讶。 :) 我并没有按照我原本打算的方式解决问题,但是对于实际问题有一个简单的解决方案:

trait UsedProvider {
  def createUsed = Used.apply _
}

class Main { this: Storage with UsedProvider =>
  val used = createUsed(...)
}

然后我将在测试中执行以下操作:new Main with StubStorage with StubUsedProvider

【问题讨论】:

    标签: scala


    【解决方案1】:

    我也没有解决您最初的问题,但您是否考虑过为Main 使用抽象类并在您需要的地方为used 提供值?

    abstract class Main { this: Storage =>
      val s = "s"
      val used: Used
    }
    

    然后像这样实例化:

    val main = new Main with StubStorage { val used = new Used(s) with StubStorage }
    

    【讨论】:

    • 那只会让我创建一个并且我需要多个,这在原始问题中并不清楚。我需要的是一种工厂方法,它允许我在需要时创建它们。所以我只是再次使用好的 ol' cake 模式来给我这种依赖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多