在Scala中用另一个性状继承自型性状
我正在尝试为我的应用程序设计一个小模块系统,这样我就可以做到:在Scala中用另一个性状继承自型性状,scala,Scala,我正在尝试为我的应用程序设计一个小模块系统,这样我就可以做到: new MyApplication extends Module1 with Module2 ... with ModuleN 为了让我的模块在应用程序中注册,我还拥有: trait ModuleRegistry { def register(start: () => Unit) = // Stores start functions in a list } trait Module { self: ModuleR
new MyApplication extends Module1 with Module2 ... with ModuleN
为了让我的模块在应用程序中注册,我还拥有:
trait ModuleRegistry {
def register(start: () => Unit) = // Stores start functions in a list
}
trait Module {
self: ModuleRegistry =>
self.register(start)
def start(): Unit
}
class Application extends ModuleRegistry {
}
trait Module1 extends Module {
...
}
其思想是,模块可以向注册表注册一个函数,以便在应用程序启动时调用。不幸的是,Scala编译器迫使我这样做:
trait Module1 extends Module {
self: ModuleRegistry =>
}
这意味着一个模块的所有实现都必须使用注册表显式地自类型,而理想情况下,它们对注册表一无所知
因此,我的问题是:
这不是蛋糕模式的一个好用法,因为您希望所有模块都保留它们自己的功能(大概是这样),而不是在混合时相互混合和覆盖。如果你想要后者,你就不应该这样做:只有非常仔细的设计才能产生可预测和合理的结果,如果第三方应该提供模块,那么设计就不会那么仔细了 相反,你应该坚持“偏好组合而非继承”的建议
这是假设一个模块可以使用单例。如果您需要一个特定的实例,您可以在伴随对象中重写apply(语法为Module1()),或者添加Module1扩展的生成器特性(例如
trait ModuleBuilder{def module:module}
)。这比您想象的更糟糕。假设Module1
和Module2
都定义start
。。。。
trait Module {
def start: Unit
}
trait Modular {
protected def moduleList: Seq[Module]
protected def register() = moduleList.map(m => m.start _)
}
class Application(modules: Module*) extends Modular {
protected def moduleList: Seq[Module] = modules // Fix varargs type
protected val registered = register()
}
object Module1 extends Module {
def start = println("One")
}
object Module2 extends Module {
def start = println("Two")
}
val app = new Application(Module1, Module2) {
registered.foreach(_())
}
// Prints "One", then "Two"