如果我有多种方法来创建对象,我应该在我的随播对象中使用多个 apply 方法吗?如果有多个应用方法,我会更难看一个。但是,如果我有多种方法来构造我的对象,这意味着我将回到我在java中使用的标准构建器模式。 (的 Companion.forBla.withBla.withBla )
答案 0 :(得分:6)
您需要区分builder和factory method。
构建器用于避免伸缩构造函数,您可以在其中创建多个构造函数,以使用户能够创建具有不同属性的对象。因此,在伴随对象中使用多个apply
方法会导致这种伸缩构造函数,并可能导致混乱的代码(反模式)。一个例子是:
case class ComplexClass(foo: String, bar: Int)
case class ComplexClassBuilder(foo: Option[String], bar: Option[Int]){
def withFoo(f: String) =
this.copy(foo = Some(f))
def withBar(b: Int) =
this.copy(bar = Some(b))
def finish = {
// this is the place to decide what happens if there are missing values
// possible ways to handle would be to throw an exception, return an option or use defaults
ComplexClass(foo getOrElse ":D", bar getOrElse 42)
}
}
工厂方法通常用于启用多态。 apply
方法是实现工厂方法的好方法
trait C
case class Foo() extends C
case class Bar() extends C
object C {
def apply(isAwesome: Boolean): C = isAwesome match {
case true => Foo()
case false => Bar()
}
}
但与往常一样,那些是模式而不是规则。通常使用一个或两个apply方法来允许创建具有不同参数的对象。但是,如果需要设置许多不同的值,则应避免使用apply
方法并实现构建器。
答案 1 :(得分:2)
你的问题听起来像是一种观点或品味。 (为什么你认为有多个apply
方法是丑陋的?)。
方法参数可以有默认值,参数可以命名为:
class MySomething(val one: String, val two: Int)
object MySomething {
def apply(one: String = "hello", two: Int = 0) = new MySomething(one, two)
}
// Creates a MySomething with one = "hello" and two = 0
val a = MySomething()
// Creates a MySomething with one = "bye" and two = 0
val b = MySomething("bye")
// Creates a MySomething with one = "hello" and two = 2
val c = MySomething(two = 2)