2013-12-17 30 views

回答

5

你需要一个builderfactory 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() 
    } 
} 

的一个好办法,但一如既往,那些图案不是规则。通常使用一种或两种应用方法来创建具有不同参数的对象。但是,如果您需要设置许多不同的值,则应该避免使用方法并实施构建器。

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)