是否存在使用Builder模式创建的对象不可变的约定?

时间:2015-09-29 21:52:41

标签: java design-patterns constructor immutability builder

根据“设计模式:可重用面向对象软件的元素”一书,

  

Builder Pattern将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示。

通常,Builder模式通过提供逐步构建对象的方法并提供实际返回最终Object的方法,解决了大量可选参数和不一致状态的问题。

使用构建器模式,我们将使用构建方法来生成一个不可变的对象。

我的问题:

我可以在生成对象的Class中使用构建器模式保持setter方法,允许改变构建对象的可能性吗?

如果我去制作可变对象,我不应该使用构建器模式?

2 个答案:

答案 0 :(得分:8)

构建器模式旨在用可选参数替换所谓的伸缩构造函数(对@scottb点头)而不是其他。它不要求对象是不可变的。

此外,构建器通常包含构造(a.k.a. build)时间时重要的属性,因此名称构建器。它不应该包含在对象生命周期内发生变化的属性,但在构造之后并不重要。

从概念上讲,如果你有一个Child的构建器,那么最重要的三件事就是momdadchildGenes(男孩/女孩,其他遗传材料)。 孩子的身高或体重不应该是建设者的一部分,因为它会被基因部分驱动,但会不断变化,超出出生时(或“建立”时间)的因素。 / p>

那就是说,除非你真的需要它,否则最好让对象不可变。

希望有所帮助!

答案 1 :(得分:7)

Builder模型中的价值不仅仅是帮助解决伸缩参数问题。

  • 他们可以让客户更容易使用API​​,因为setter方法是自我命名的,因此更容易记住。
  • Builder Pattern启用了可选参数,只有通过使用可能不方便的重载才能为telescoping构造函数提供这些参数。
  • 使用构建器的客户端代码可以比使用构造函数的代码更自我记录,从而使客户端代码更容易(并且更便宜)维护
  • Builder Pattern可以减少错误。可以使用伸缩构造器意外地转换相同类型参数的大列表。在这种情况下,编译器不会报告错误,并且导致的错误可能会被远远删除,并且难以追踪。
  • 可以在Builder的构造函数签名中指定对象的必需参数。编译器将坚持在编译时始终提供这些必需参数。
  • 有用的API随着时间的推移而发展;将setter方法添加到构建器对象很容易,同时管理一组重载的构造函数可能不那么容易且更容易出错。
  • Builder Pattern兼容并发。保持可变构建器对象线程受限,因此线程安全是相对简单的。

构建器对于构造不可变对象特别有用,因为对于此类对象,必须在构建时提供所有数据。当需要提供大量数据或必须完成多个步骤时,很容易推荐Builder模式。

没有规则构建器对象不能构建可变对象,但是对于可变对象,JavaBeans模式提供了相同的好处(易于阅读,自我记录,减少了容易出错),代码更少。