【发布时间】:2014-07-29 20:44:26
【问题描述】:
我想完成什么
我想利用策略模式,而策略类具有类型参数。
代码是什么样子的
假设我有以下通用抽象策略类:
abstract class Strategy[T, V]() {
def doSomething(x: Int): V
def unDoSomething(x: V): T
}
我现在得出两个具体的策略:
class StrategyOne() extends Strategy[Int, String] {
def doSomething(x: Int): String = { x.toString() }
def unDoSomething(x: String): Int = { x.toInt }
}
class StrategyTwo() extends Strategy[Double, List[Int]] {
def doSomething(x: Int): List[Int] = { List(x, 10, 20)}
def unDoSomething(x: List[Int]): Double= { x.reduceLeft(_ + _) + 0.1 }
}
现在,我们有一个使用该策略的类:
class Worker[T, V](strategy: Strategy[T, V]) {
def run() {
val res = strategy.doSomething(5) //res is a T
val res2 = strategy.unDoSomething(res) //res2 is a V
println(res2)
}
}
正如预期的那样,我现在能够实例化没有显式类型的新工作人员:
val worker1 = new Worker(new StrategyOne())
val worker2 = new Worker(new StrategyTwo())
问题
不过,我也想利用某种动态策略选择,像这样:
val strategies = Map("one" -> new StrategyOne(), "two" -> new StrategyTwo())
val worker = new Worker(strategies(args(0)))
自然地,编译器告诉我,我想要的是不可能的,因为无法推断出任何类型。
问题
我知道这个星座很不幸,但我需要Worker 中的T 和V 类型。
是否有可能使这种模式适用于这种特定情况?
【问题讨论】:
-
我刚拿了你的代码,复制粘贴到工作表中。通过一些非常小的调整,它似乎可以工作,我看不出有什么理由不这样做。你能提供编译器的实际错误吗? (我测试的代码是gist.github.com/agenovese/82dc31743641f059adf2,评论太长,不是真正的答案,所以我把它链接了)
-
@AngeloGenovese,谢谢。请尝试使用 StrategyOne 和 StrategyTwo 中函数内的所有值。我会更新问题。
-
另外,我在 REPL 中重新检查了我的示例,在这种情况下,它确实可以编译。但是请注意,映射策略的类型例如变为
_ >: Double with Int <: AnyVal。从长远来看,这会破坏我的代码。
标签: scala oop generics type-inference