我正在用 Scala 编写一个项目。该项目涉及一组特性和一组配置,两者都是可扩展的。“可扩展”是指稍后我将在层次结构中添加新功能,并且它们必须与任何配置一起使用而无需重新编译。这是下图的特征层次结构:
trait Feature {
def apply(board: Board)
}
class Foo extends Feature {
def apply(board: Board) {
println(board formatted "Foo: %s")
}
}
class Bar extends Feature {
def apply(board: Board) {
println(board formatted "Bar: %s")
}
}
配置基本上只是为 a 定义了很多参数Board
,包括每个Feature
. 在运行时创建配置有几种可能的策略:预定义的、随机的、使用用户提供的值等。理论上,我希望能够编写这样的东西(不是有效的 Scala 代码!):
abstract class Config(val param: Int) {
val ConfigParameter: Int
def featureCount[T <: Feature]: Int
}
object Config {
def makeBasic(param: Int) = new Config(param) {
val ConfigParameter = param
def featureCount[Foo] = 3
def featureCount[Bar] = 7
}
def makeRandom(param: Int) = new Config(param) { ... }
def makeWithUserValues(param: Int, ...) = new Config(param) { ... }
def makeByStandardISO1234567(param: Int) = new Config(param) { ... }
}
class Board(val config: Config) { ... }
显然,它不会编译。我的问题是:用 Scala 表示这个可扩展系统的最佳方式是什么?我总是可以在 中包含类似Map[Class, Int]
的东西,但它不是类型安全的:程序员可以在非sConfig
中插入类。那么,在 Scala 类型系统中是否有一种方法可以表示类似其中的不同键可能是不同子类型的东西?或者,也许有一些方法可以将所有这些行为转移到层次结构中?Map
Feature
Map[Class[T <: Feature], Int]
Map
Feature
Feature
谢谢你。