此代码模式的用途是什么?



我正在调试别人的代码,我只是不明白用Java以这种方式编码的好处。

我不是 Java 设计模式专家,但我想知道什么时候适用?

public class MyClass {
public static class Builder {
//Getters and setters
}
public static Builder newBuilder() {
return new Builder();
}
public MyClass(Builder builder) {
//More Methods
}
public static void main(String[] args) {
MyClass.Builder builder = MyClass.newBuilder();
new MyClass(builder);
}
}

这是一个构建器模式几乎没有错误设置的实现:

生成器设计模式的目的是将复杂对象的构造与其表示形式分开。通过这样做,相同的构造过程可以创建不同的表示。

这里奇怪的是,Builder类的构造函数是从MyClass调用的。通常不会这样做,因为将MyClass类与Builder联系起来,反之亦然。

此外MyClass构造函数应该private,以便没有人可以直接访问它,而只能使用Builder

正确的实现应如下所示:

public class MyClass {
// Often fields are final to create an immutable class
private final String fieldA;
// Private constructor using Builder to set inner fields
// To create MyClass you have to use Builder
private MyClass(Builder builder) {
// Setting fields from builder
this.a = builder.getFieldA();
}
public static class Builder {
// Fields on Builder are not final
private String fieldA;
//Getters and setters
// Method to set field of builder
public Builder setFieldA(String a) {
this.a = a;
return this;   // Returning this to chain setters
}
...
// Method to instantiate MyClass
public MyClass build() {
return new MyClass(this);
}
}
}
// Calling it as follow
MyClass a = new MyClass.Builder()
.setFieldA("value")
.setFieldB("value")
.build();

根据命名,这看起来像是创建模式之一 - 生成器模式。但是,这个没有得到很好的实施。

此模式的目的是编写可读且干净的代码来创建非常复杂的对象。一个很好但简单的例子是StringBuilder。它通常通过流畅的接口实现 - 一个典型的例子是Stream<T>.

例如,正确的实现是这里。它允许您使用返回构建器的方法创建对象。例:

MyClass foo = MyClass.newBuilder()
.cached()
.with(new Feature1())
.with(new Feature2())
.foo()
.bar()
.build();

我个人对这种模式的看法:

它鼓励创建和使用复杂的对象。我更喜欢重构一个对象,该对象具有具有较小组件的构建器。该对象变得易于测试和创建,只能通过构造函数创建。

Builder 模式公开了所谓的 Fluent API。您可以链接资源库,然后是最终的构建方法来获取类实例,而不是在每行上进行单独的集合调用。构建器对象上通常没有 getter。

该构造函数是复制构造函数的一种形式。我猜还有其他代码使用它来构建具有相同数据的对象的唯一实例。

main 方法的最后一行没有执行任何操作,因为您没有分配该新类。无论如何,如前所述,您通常使用构建方法,而不是将构建器传递到构造函数中。

MyClass foo = MyClass.newBuilder()
.withBar("blah")
.build();

MyClass.newBuilder()也可以用new MyClass.Builder()取代

最新更新