【发布时间】:2019-10-08 17:07:40
【问题描述】:
这是我面临的问题:
我有一个抽象特征Toggles,它有一个抽象方法isToggleEnabled(name: String)。
我想要的是能够拥有具有isToggleEnabled 的具体实现的生产环境特征ProdToggles 并在产品代码中使用它,但能够提供具有新实现@987654326 的覆盖替代特征TestToggles @测试时。
原因是生产环境实现使用系统属性来存储切换名称及其状态,但是在测试中我想提供不同的实现来存储和读取切换,以便多个测试可以并行运行而不会相互影响(就像通过系统属性一样)。我想出使用蛋糕图案的方法:
trait Toggleable {
def isToggleEnabled(name: String): Boolean
}
trait ProdToggles extends Toggles with Toggleable {
override def isToggleEnabled(name: String): Boolean = System.getProperty("name").toBoolean
}
trait TestToggles extends Toggles with Toggleable {
val cache = scala.collection.mutable.HashMap.empty[String, Boolean]
override def isToggleEnabled(name: String): Boolean = cache.getOrElse(name, false)
}
trait Toggles {
this: Toggleable =>
def isEnabled(name: String): Boolean = {
isToggleEnabled(name)
}
}
//—————IN PROD code—————
class Prod() {
this: Toggles =>
def doSomething(): Unit ={
isEnabled("toggle.name")
}
}
object Prod {
def apply(): Prod = new Prod with ProdToggles
def apply(testing: Boolean) = new Prod with TestToggles
}
//——————IN TEST code———————————
class Tests {
val prod = Prod(true)
prod.doSomething()
}
但是,问题在于:
- 打破封装和
Prod实例可能被误用为Toggle实例,就像(new Prod with ProdToggles).{isEnabled, isToggleEnabled, doSomething}一样 - 每个
Prod类 mixinToggles都需要一个object和apply工厂来返回自定义实例以用于测试和生产 - Cake-pattern 是一种反模式
您还有其他方法可以解决这个问题吗?谢谢!
【问题讨论】:
标签: scala design-patterns