假设我有以下特征来定义一个接口并采用几个类型参数......
trait Foo[A, B] {
// implementation details not important
}
Run Code Online (Sandbox Code Playgroud)
我想使用伴侣对象作为特征的具体实现的工厂.我还想强制用户使用Foo
接口而不是子类化所以我隐藏了伴随对象中的具体实现,如下所示:
object Foo {
def apply[A, B](thing: Thing): Foo[A, B] = {
???
}
private case class FooImpl[A1, B1](thing: Thing) extends Foo[A1, B1]
private case class AnotherFooImpl[A2, B1](thing: Thing) extends Foo[A2, B1]
}
Run Code Online (Sandbox Code Playgroud)
我希望能够按如下方式使用工厂:
val foo = Foo[A1, B1](thing) // should be an instance of FooImpl
val anotherFoo = Foo[A2, B1](thing) // should be an instance of AnotherFooImpl
Run Code Online (Sandbox Code Playgroud)
如何实现该apply
方法以实现此目的?这个SO帖子似乎接近标志.
怎么样:
trait Foo[A, B]
trait Factory[A, B] {
def make(thing: Thing): Foo[A, B]
}
class Thing
object Foo {
def apply[A, B](thing: Thing)(implicit ev: Factory[A, B]) = ev.make(thing)
private case class FooImpl[A, B](thing: Thing) extends Foo[A, B]
private case class AnotherFooImpl[A, B](thing: Thing) extends Foo[A, B]
implicit val fooImplFactory: Factory[Int, String] = new Factory[Int, String] {
override def make(thing: Thing): Foo[Int, String] = new FooImpl[Int, String](thing)
}
implicit val anotherFooImplFactory: Factory[String, String] = new Factory[String, String] {
override def make(thing: Thing): Foo[String, String] = new AnotherFooImpl[String, String](thing)
}
Run Code Online (Sandbox Code Playgroud)
现在:
def main(args: Array[String]): Unit = {
import Foo._
val fooImpl = Foo[Int, String](new Thing)
val anotherFooImpl = Foo[String, String](new Thing)
println(fooImpl)
println(anotherFooImpl)
}
Run Code Online (Sandbox Code Playgroud)
产量:
FooImpl(testing.X$Thing@4678c730)
AnotherFooImpl(testing.X$Thing@c038203)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1650 次 |
最近记录: |