受我对通用策略模式的 C# 实现的启发,我想在 Scala 中做同样的事情。我还想做一些函数式编程来将策略算法封装在继承的类中。所以我所做的是:
trait Strategy {
type T <: Strategy
type O
def Call(victim: T): O = {
strategy(victim)
}
var strategy: (this.T => this.O)
}
这是一个特征,它是烫伤的基础。我也有一StrategyFactory
堂课:
case class StrategyFactory[T <: Strategy, O](str: T) {
def Call(x: (T => O)) = x(str)
}
object StrategyFactory {
}
最后在我的代码中,我可以创建具体的策略:
class DownloadStrategy(path: String) extends Strategy {
type T = DownloadStrategy
type O = String
strategy = (dw: DownloadStrategy) => path + "aaaa"
}
object DownloadStrategy {
def apply(s: String) = new DownloadStrategy(s)
}
在我的应用程序代码中,我有这个:
var ds = DownloadStrategy("j")
val m = StrategyFactory[DownloadStrategy, String](ds)
var output = m.Call(ds.strategy)
这里一切正常。
我想要功能性策略,因此有m.Call(ds.strategy)
但这是非常虚拟的设计,因为我无法创建一组将要扩展的类DownloadStrategy
。例如:
class ImageDownloadStrategy(w: String, h: String, path: String) extends DownloadStrategy(path){
type T = ImageDownloadStrategy
type O = String
strategy = (ids: T) => path + ":ImageDownloadStrategy"
}
class VideoDownloadStrategy(w: String, h: String, path: String) extends DownloadStrategy(path){
type T = VideoDownloadStrategy
type O = String
strategy = (ids: T) => path + ":VideoDownloadStrategy"
}
等等。基本上我想拥有一些默认策略的基类,而子类是更具体的实现。
这让我想到了应用程序代码,我想在其中编写如下代码:
var ds: DownloadStrategy = null
request.getQueryString("t") match {
case "1" => ds = ImageDownloadStrategy("","","")
case "2" => ds = VideoDownloadStrategy("","","")
case "3" => ds = RawFileDownloadStrategy("","","")
case _ => ds = DownloadStrategy("")
}
var output = (StrategyFactory[DownloadStrategy, String](ds)).Call(ds.strategy)
我认为当我编写StrategyFactory[DownloadStrategy, String](ds)
编译器时,它会非常聪明,可以计算出 willImageDownloadStrategy
的子类DownloadStrategy
是否可以让我进行一些多态调用,但我做不到。
另一个事实是我需要覆盖type T
并type O
在交付的课程中,DownloadStrategy
但我不知道该怎么做。
请给我一些建议如何模拟这种行为。
编辑(对于 pagoda_5b 的详细信息)
正如我所提到的,我有功能var strategy
in trait Strategy
which is var strategy: (this.T => this.O)
。这个变量需要在实现这个特性的类中被覆盖。我还有 2 个泛型类型,这T
意味着具体策略的子类,并O
指示来自def Call(...)
.
我想要实现的是在 Strategy 的子类中拥有功能策略,然后进行多态调用。在这里,我得到了DownloadStrategy
默认策略,并且我有一些带有特定算法的子类。我想ImageDownloadStrategy
转换DownloadStrategy
并使用它,就像我在 switch case 语句中展示的那样。