我(缺少更好的术语)封装构造对象的工厂方法:
def createMyObject = new SomeClass(a, b, c, d)
现在,根据上下文,我需要将一个或多个特征混合到SomeClass中:
new SomeClass with Mixin1
或
new SomeClass with Mixin2 with Mixin3
而不是为每个"类型"创建多个单独的工厂方法。实例化,我如何传入要混合的特征,以便可以用一个方法完成?或者也许有一个很好的模式,结构不同?
我想保持封装,所以我不希望每个消费者只是自己创建这个类。
答案 0 :(得分:3)
如果只需要mixins而没有方法覆盖,则可以使用类型类:
trait Marker
class C[+T <: Marker] { def b = 1 }
trait Marker1 extends Marker
implicit class I1[T <: Marker1](c: C[T]) {def a = 6 + c.b}
trait Marker2 extends Marker
implicit class I2[T <: Marker2](c: C[T]) {def a = 5 + c.b}
trait Marker3 extends Marker
implicit class I3[T <: Marker3](c: C[T]) {def k = 100}
trait Marker4 extends Marker3
implicit class I4[T <: Marker4](c: C[T]) {def z = c.k + 100} //marker3's `k` is visible here
scala> def create[T <: Marker] = new C[T]
create: [T <: Marker]=> C[T]
scala> val o = create[Marker1 with Marker3]
o: C[Marker1 with Marker3] = C@51607207
scala> o.a
res56: Int = 7
scala> o.k
res57: Int = 100
scala> create[Marker4].z
res85: Int = 200
但它不会对create[Marker1 with Marker2].a
(含糊不清的含义)起作用,所以这里没有线性化。但是如果你想混合一些方法(比如javascript&#39; s原型)并且可能注入一些东西 - 似乎没问题。您还可以将它与传统的线性化混合相结合,为C,I1,I2等添加一些特性。
答案 1 :(得分:0)
您可以根据上下文不同地实例化类。
def createMyObject =
if (context.foo)
new SomeClass
else
new SomeClass with Mixin1
但是,如果消费者知道应该混入的特征,那你为什么不在那里实例化呢?