我想知道在scala中实现工厂模式/方法的最佳做法是什么?
说我们有这样的对象:
case class foo1(a:Int,b:String)
case class goo1(z:Double, w:String)
如何以通用的方式创建它们[可能使用特征等...]?
感谢
答案 0 :(得分:0)
如果您的目标是编写自己的依赖注入模块,即动态提供实例,我强烈建议您查找一些现有工具。对“Scala依赖注入框架”进行简单的Google搜索会产生许多结果,例如MacWire
,Guice
,ReaderMonad
,cake pattern
等。
然而,我的判断除了你的动机,并且只是回答这个问题的一种方式,你会在scala中做到这一点也是类型安全的:
trait FactoryMethod[T] {
type Args
def defaultArgs: Args
def withArgs(args: Args): T
def default: T = withArgs(defaultArgs)
}
case class Foo(a:Int,b:String)
object Foo {
implicit object factory extends FactoryMethod[Foo] {
override type Args = (Int,String)
override def withArgs(args: Args): Foo = (Foo.apply _).tupled(args)
override def defaultArgs: Args = (1,"foo")
}
}
case class Goo(z:Double, w:String)
object Goo {
implicit object factory extends FactoryMethod[Goo] {
override type Args = (Double,String)
override def withArgs(args: Args): Goo = (Goo.apply _).tupled(args)
override def defaultArgs: Args = (2L,"goo")
}
}
object Factory {
def of[T](implicit factory: FactoryMethod[T]): factory.Args => T = factory.withArgs
def instanceOf[T](implicit factory: FactoryMethod[T]): T = factory.default
}
//obtain instance with default arguments
Factory.instanceOf[Goo]
//type safe way of obtaining instance with custom fed arguments
Factory.of[Foo].apply((-22,"baz"))
//By type safe I mean that the line below won't compile because the
//arguments fed for Foo are not compatible:
//Factory.of[Foo].apply(("bar","baz"))
//Note that if you abstract over the types Goo and Foo like this:
//def myMethod[T]: T = {
// Factory.instanceOf[T]
//}
//It won't compile unless you also ask for the needed implicit
//on the method signature
def myMethod[T: FactoryMethod]: T = {
Factory.instanceOf[T]
}