是否存在使用 Builder 模式创建的对象不可变的约定?
Is there a convention that objects created using the Builder pattern be immutable?
根据《设计模式:可重用面向对象软件的元素》一书,:
The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations.
通常,Builder 模式通过提供一种逐步构建对象的方法并提供一种实际 return 最终对象的方法来解决大量可选参数和不一致状态的问题.
使用构建器模式,我们将有一个生成对象的构建方法是不可变的。
我的问题:
我可以使用构建器模式在生成对象的 Class 中保留 setter 方法,从而允许改变构建的对象吗?
如果我去生产可变对象,我不应该使用构建器模式?
Builder Pattern 旨在替换所谓的伸缩构造函数(向@scottb 致敬)可选参数,而不是还有很多。它不要求 object 是不可变的。
此外,构建器通常 仅 包含在 构建(a.k.a.build)时间 时重要的属性,因此名字 建造者。它不应包括在 object 的生命周期内发生变化但在构建后并不重要的属性。
从概念上讲,如果您有 Child
的生成器,唯一重要的三件事是 mom
、dad
和 childGenes
(boy/girl, 其他遗传 material). child 的身高或体重不应成为建造者的一部分,因为它部分受基因驱动,但会因出生时存在的因素(或"build"次)。
也就是说,除非你真的需要它,否则最好让 object 不可变。
希望对您有所帮助!
Builder Pattern 的价值不仅仅在于帮助解决伸缩参数问题。
- 它们可以使 API 更易于客户使用,因为 setter 方法是自命名的,因此更容易记住。
- Builder Pattern 启用可选参数,伸缩构造函数只能通过使用可能笨拙的重载来提供。
- 使用构建器的客户端代码可以比使用构造函数的代码更自文档化,从而使客户端代码更容易(并且更便宜)维护
- Builder Pattern 可以减少错误。使用伸缩构造函数可能会意外地转置大量相同类型的参数。在这种情况下,编译器不会报告错误,由此产生的错误可能会被远远移除并且难以追踪。
- 可以在Builder 的构造函数签名中指定对象的强制参数。编译器会坚持这些强制参数总是在编译时提供。
- 有用的 API 会随着时间的推移而演变;向构建器对象添加 setter 方法很容易,而管理一组重载的构造函数可能不那么容易且更容易出错。
- 构建器模式是并发友好的。保持可变构建器对象线程受限相对简单,因此线程安全。
构建器对于构建不可变对象特别有用,因为对于此类对象,必须在构建时提供所有数据。当需要提供大量数据或者必须完成多个步骤时,构建器模式非常容易推荐。
没有规定构建器对象不能构建可变对象,但是对于可变对象,JavaBeans 模式以更少的代码提供了相同的好处(易读性、自我记录、减少错误倾向)。
根据《设计模式:可重用面向对象软件的元素》一书,:
The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations.
通常,Builder 模式通过提供一种逐步构建对象的方法并提供一种实际 return 最终对象的方法来解决大量可选参数和不一致状态的问题.
使用构建器模式,我们将有一个生成对象的构建方法是不可变的。
我的问题:
我可以使用构建器模式在生成对象的 Class 中保留 setter 方法,从而允许改变构建的对象吗?
如果我去生产可变对象,我不应该使用构建器模式?
Builder Pattern 旨在替换所谓的伸缩构造函数(向@scottb 致敬)可选参数,而不是还有很多。它不要求 object 是不可变的。
此外,构建器通常 仅 包含在 构建(a.k.a.build)时间 时重要的属性,因此名字 建造者。它不应包括在 object 的生命周期内发生变化但在构建后并不重要的属性。
从概念上讲,如果您有 Child
的生成器,唯一重要的三件事是 mom
、dad
和 childGenes
(boy/girl, 其他遗传 material). child 的身高或体重不应成为建造者的一部分,因为它部分受基因驱动,但会因出生时存在的因素(或"build"次)。
也就是说,除非你真的需要它,否则最好让 object 不可变。
希望对您有所帮助!
Builder Pattern 的价值不仅仅在于帮助解决伸缩参数问题。
- 它们可以使 API 更易于客户使用,因为 setter 方法是自命名的,因此更容易记住。
- Builder Pattern 启用可选参数,伸缩构造函数只能通过使用可能笨拙的重载来提供。
- 使用构建器的客户端代码可以比使用构造函数的代码更自文档化,从而使客户端代码更容易(并且更便宜)维护
- Builder Pattern 可以减少错误。使用伸缩构造函数可能会意外地转置大量相同类型的参数。在这种情况下,编译器不会报告错误,由此产生的错误可能会被远远移除并且难以追踪。
- 可以在Builder 的构造函数签名中指定对象的强制参数。编译器会坚持这些强制参数总是在编译时提供。
- 有用的 API 会随着时间的推移而演变;向构建器对象添加 setter 方法很容易,而管理一组重载的构造函数可能不那么容易且更容易出错。
- 构建器模式是并发友好的。保持可变构建器对象线程受限相对简单,因此线程安全。
构建器对于构建不可变对象特别有用,因为对于此类对象,必须在构建时提供所有数据。当需要提供大量数据或者必须完成多个步骤时,构建器模式非常容易推荐。
没有规定构建器对象不能构建可变对象,但是对于可变对象,JavaBeans 模式以更少的代码提供了相同的好处(易读性、自我记录、减少错误倾向)。