Builder Design Pattern的歧义

时间:2015-06-01 06:24:41

标签: design-patterns builder

我对Builder Pattern有几个问题。 Builder Pattern使用多种方法构造类的实例,每个方法返回this作为返回值。

我的问题是:

  1. 为什么每个方法都返回同一个类的返回类型实例?
  2. 这种模式与使用setter方法相比有什么好处?

3 个答案:

答案 0 :(得分:1)

您可以在不让方法返回this的情况下实现构建器模式。但是让方法返回同一个类的实例的好处是可以将方法链接在一起。例如:

return new ObjectBuilder().withWidget("A").withGadget(5).build();

使用模式的主要原因(在构造对象上的setter)是将构建对象的逻辑与对象本身分开。通常,这意味着构建的对象没有公共setter,这大大简化了它。但是,它可能需要非常复杂的构造函数或受保护的setter来支持构建器。

答案 1 :(得分:1)

  
      
  1. 为什么每个方法都返回同一个类的返回类型实例?
  2.   

这不是绝对必要的。你可以返回别的东西(或无效)。返回Builder使其成为流畅的构建器,这意味着您可以方便地链接方法调用,也许可以避免显式引用构建器:

Built thing = new Built.Builder().setFoo("bar").build();

Vs的

Builder builder = new Builder();
builder.setFoo("bar");
Built built = builder.build();

请注意,每个链接的呼叫都会将另一个呼叫推送到堆栈,因此您可以限制您可以进行的链接呼叫数量 - 尽管您几乎不可能遇到此问题。

另外,使Builder流畅的确会创建更多样板代码 - 如果你创建了大量的setter方法,那么在每个方法结束时必须return this会很烦人。 / p>

  
      
  1. 这种模式与使用setter方法相比有什么好处?
  2.   

一个好处是构建对象的不可变性的可能性,以及提供的所有期望属性(与不受信任的客户端安全共享实例,不需要克隆,线程安全等)。

例如:

final class Built {
  private final String foo;

  private Built(Builder builder) {
    this.foo = builder.foo;
  }

  String getFoo() { return foo; }

  static final class Builder {
    private String foo;

    Built build() { return new Built(this); }
    Builder setFoo(String value) { this.foo = value; return this; }
  }
}

Built的实例是不可变的,因为没有可变状态,并且禁止继承。这意味着如果我给你一个Built的实例(或者你给我一个实例),那么我知道你不能做一些事情随后改变它 - 没有必要推断状态变化。< / p>

答案 2 :(得分:1)

生成器模式类似于工厂模式,但用于复杂的构造。这意味着您将工厂接口设置为相关实现,但在构建器模式中,此结构用于复杂构造。