あなたの目標は、オンザフライでインスタンスを提供し、独自の依存性注入モジュールを書くことであるならば、私は強くあなたが既存のツールのいくつかを検索することをお勧めしたいです。 「Scalaの依存性注入フレームワーク」のためのシンプルなGoogle検索では、このようなMacWire
、Guice
、ReaderMonad
、cake pattern
として多くの結果が得られると、などでしょう
私はさておき、あなたの動機から判断し、単に質問に答えるためには、ここであなたは1つの方法ですがタイプセーフであるスカラーでこれを行うでしょう:
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]
}
この質問には十分なコンテキストと詳細がありません。どのような意味での 'Generic'? – andyczerwonka
最初のベストプラクティスは、クラス宣言に関する命名規則に従うことです。 – cchantep