Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用生成器模式创建的对象是否有不可变的约定?_Java_Design Patterns_Constructor_Immutability_Builder - Fatal编程技术网

Java 使用生成器模式创建的对象是否有不可变的约定?

Java 使用生成器模式创建的对象是否有不可变的约定?,java,design-patterns,constructor,immutability,builder,Java,Design Patterns,Constructor,Immutability,Builder,根据《设计模式:可重用面向对象软件的元素》一书: 生成器模式将复杂对象的构造与其表示分离,以便相同的构造过程可以创建不同的表示 通常,构建器模式通过提供一种逐步构建对象的方法,并提供一种实际返回最终对象的方法,解决了大量可选参数和不一致状态的问题 使用构建器模式,我们将有一个构建方法来生成一个不可变的对象 我的问题: 我可以在generate对象的类中使用builder pattern keeping setters方法,允许对构建对象进行变异吗 如果我要生成可变对象,我不应该使用生成器模式 构

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

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

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

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

我的问题:

我可以在generate对象的类中使用builder pattern keeping setters方法,允许对构建对象进行变异吗


如果我要生成可变对象,我不应该使用生成器模式

构建器模式旨在取代所谓的伸缩构造函数(向@scottb点头),以获得可选参数,而不是其他太多。它不要求对象是不可变的

此外,构建器通常只应包括在构建(又称构建)时起作用的属性,因此命名为构建器。它不应该包括在对象的生命周期内发生变化但在构建后实际上并不重要的属性

从概念上讲,如果你有一个孩子的构建器,那么唯一重要的三件事就是妈妈、爸爸和孩子基因(男孩/女孩,其他遗传物质)孩子的身高或体重不应成为构建者的一部分,因为它将部分由基因驱动,但会因出生时(或“构建”时间)以外的因素而不断变化

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


希望有帮助

构建器模式的价值不仅仅是帮助解决伸缩参数问题

  • 它们可以使客户端更容易使用API,因为setter方法是自命名的,因此更容易记住
  • 构建器模式启用可选参数,伸缩构造函数只能通过使用潜在的笨拙重载来提供这些参数
  • 与使用构造函数的代码相比,使用构建器的客户机代码可以更自我记录,从而使客户机代码更易于维护(也更便宜)
  • 生成器模式可以减少bug。相同类型参数的大型列表可能会意外地使用伸缩构造函数进行转置。在这种情况下,编译器不会报告错误,由此产生的错误可能会被清除得很远,很难追踪
  • 对象的强制参数可以在生成器的构造函数签名中指定。编译器将坚持在编译时始终提供这些强制参数
  • 有用的API会随着时间的推移而发展;将setter方法添加到builder对象很容易,而管理一组重载构造函数则不那么容易,而且更容易出错
  • 生成器模式是并发友好的。相对而言,将可变构建器对象线程保持在受限状态,从而保持线程安全是比较简单的
构建器对于构建不可变对象特别有用,因为对于此类对象,必须在构建时提供所有数据。当需要提供大量数据或必须完成多个步骤时,构建器模式非常容易推荐


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

您试图解决的实际问题是什么?你是在问你是否编写了一个构建器来构建一个可变对象,还是有其他原因让你担心?@DanielPryden在工作时我发现了这个模式的实现,但它允许修改构建对象,所以我问自己,如果这个动作打破了这个模式的一个提议,那就是构建一个不可变的对象。构建的对象甚至可以有可链接的setter,因此您可以执行
obj.setA(..).setB(..)
。。。构建器本身就是这样一个可变对象。