我已经看到了两种实现构建器模式的流行方法:
// 1. The build() approach
Product p = builder.part1()
.part2()
.build();
// 2.The constructor approach
builder.part1()
.part2();
Product p = new Product(builder);
哪一种更可取?
答案 0 :(得分:6)
第一个是要走的路......
如果你使用第二选择,那么这样做:
Product p = new Product(builder);
将向Product类添加依赖项。
这意味着Product类现在至少需要一个带有参数 builder
的构造函数答案 1 :(得分:2)
问题有点模糊,但是如果你有一个静态构建器类,joshua bloch的有效java书建议的结构更像是第一个使用build方法的结构。这是一种更清洁,更安全的方式。
Product p= new Product.ProductBuilder("hw", "sw")
.version(30)
.mac("1234567")
.address("Fake address 1234")
.build();
答案 2 :(得分:1)
我倾向于使用这两个例子的组合。
我将在Product类中定义一个构建器类,并为产品类提供一个带有ProductBuilder的私有构造函数。
答案 3 :(得分:1)
这是两种不同的方法。交易是不同的。 您必须根据您的需要和背景使用和调整模式,而不是根据一个严格的规则......
使用类似的构建器:
Product p = new Product(builder);
允许创建构建器并重用它。 如果您需要重用构建器或在另一个类中创建构建器,那么这是一个很好的实现。您需要它才能打开API 解决方案的缺点是无法直接创建对象 关于设计质量和依赖性,我认为这是一个错误的问题。 对于Product的公共构造函数,可以在Product和构建器之间创建公共依赖项,并公开Product构造函数。 但是,如果在Product构造函数中,您将构建Product的任务调度到构建器实例,那么耦合是否会使代码不那么灵活?从不。实际上,由于构建器使用镜像属性来构建Product对象,因此实际耦合位于Product构造中。因此,真实和强大的耦合将保持任何发生:这两个类必须一起工作,并且必须看起来像。
使用类似的构建器:
Product p = builder.part1()
.part2()
.build();
不允许重复使用构建器,但更直接地用于类的客户端,并且它至少打开了Builder与Product之间的依赖关系。 如果您不需要重复使用构建器或在其他类中创建构建器,那么它是最好的,因为您无法以无用的方式打开API。
因此,事实上,两种解决方案都在附近。 如果我必须重用构建器,或者我需要在另一个类中创建构建器,我会使用带有构造函数的解决方案,如果不需要,我将使用不带构造函数的解决方案。