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

Jes*_*rce 2 java constructor design-patterns builder immutability

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

构建器模式将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示.

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

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

我的问题:

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

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

Pra*_*ant 9

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

此外,构建器通常应包括构造(也称为构建)时间的重要属性,因此名称构建器.它不应该包含在对象的生命周期中改变的属性,但在构造之后并不重要.

从概念上讲,如果你有一个建设者Child,只有三件事情,这将是重要的mom,在dadchildGenes(男孩/女孩,其他遗传物质).儿童的身高或体重不应该是建造者的一部分,因为它将由基因部分驱动,但会不断变化超过出生时(或"建立"时间)的因素.

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

希望有所帮助!

  • 很好的例子。 (2认同)

sco*_*ttb 7

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

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

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

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