我正在尝试设计一个类层次结构,其中包含一堆类似的类,这些类并不完全共享"是一种"关系.我们称之为这些Model课程.这些类旨在与类似算法的集合配对,这些算法使用Model类但不具有相同的要求.我们称之为这些Strategy课程.诀窍是Strategy类需要从类中获得许多相同的东西Model,但并非所有Model类都能够实现那些所需的方法.我希望没有空的"存根"方法只会抛出UnsupportedOperationExceptions,而是采用类型安全的基于mixin的方式来处理这个问题 - 我可以应用一种设计模式吗?
例如,
object Main extends App {
trait A {
def f(one: Int): Int
def g(two: Int): Int
def h(three: Int): Int
}
class A1 extends A {
override def f(one: Int): Int = {one + 1}
override def g(two: Int): Int = {two + 2}
override def h(three: Int): Int = {assert(false); 0}
}
class A2 extends A {
override def f(one: Int): Int = {assert(false); 0}
override def g(two: Int): Int = {two - 2}
override def h(three: Int): Int = {three - 3}
}
trait B {
def combine(i: Int): Int
}
trait B1 extends B {
this: A =>
override def combine(i: Int) = {f(i) + g(i)}
}
trait B2 extends B {
this: A =>
override def combine(i: Int) = {g(i) + h(i)}
}
override def main(args: Array[String]): Unit = {
val a11 = new A1 with B1
val a22 = new A2 with B2
println(a11.combine(3))
println(a22.combine(3))
val a12 = new A1 with B2
println(a12.combine(3))
}
}
Run Code Online (Sandbox Code Playgroud)
这A是一个Model班级,B是Strategy班级.请注意,A1可能无法实现h(),并且A2可能无法实现f(),并且根据策略类,这可能是也可能不是问题.我希望能够找到A的哪个实现可以在编译时使用哪个B实现.
我使用自我类型来表达一种更多的"有一种"而不是"一种"的关系,通常会延伸.
我的解决方案:
trait F { def f(one: Int): Int }
trait G { def g(two: Int): Int }
trait H { def h(three: Int): Int }
trait A
trait A1 extends A with F with G {
def f(one: Int): Int = { one + 1 }
def g(two: Int): Int = { two + 2 }
}
trait A2 extends A with G with H {
def g(two: Int): Int = { two - 2 }
def h(three: Int): Int = { three - 3 }
}
trait B {
def combine(i: Int): Int
}
trait B1 extends B {
this: A with F with G =>
def combine(i: Int) = { f(i) + g(i) }
}
trait B2 extends B {
this: A with G with H =>
def combine(i: Int) = { g(i) + h(i) }
}
val a11 = new A1 with B1
val a22 = new A2 with B2
println(a11.combine(3))
println(a22.combine(3))
val a12 = new A1 with B2 // won't compile as you wanted
Run Code Online (Sandbox Code Playgroud)