我正在调试其他人的代码,我只是不了解在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);
}
}
答案 0 :(得分:2)
这项实施的错误设置很少builder pattern:
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();
答案 1 :(得分:2)
根据命名,这看起来像一个创作模式 - Builder模式。但是,这个没有得到很好的实施。
此模式的目的是编写可读且干净的代码以创建非常复杂的对象。一个好而简单的例子是StringBuilder
。它通常使用流畅的界面实现 - 典型的例子是Stream<T>
。
正确的实现是例如here。它允许您使用返回构建器的方法创建对象。例如:
MyClass foo = MyClass.newBuilder()
.cached()
.with(new Feature1())
.with(new Feature2())
.foo()
.bar()
.build();
我个人对这种模式的观点:
它鼓励创建和使用复杂的对象。我更喜欢重构一个具有较小组件的构建器的对象。该对象只能通过构造函数轻松测试和创建。
答案 2 :(得分:1)
Builder模式公开了所谓的Fluent API。您可以链接setter,然后使用最终构建方法来获取类实例,而不是在每一行上进行单独的set调用。在构建器对象上通常不会有getter。
该构造函数是复制构造函数的一种形式。我猜测还有其他代码使用它来构建具有相同数据的对象的唯一实例。
您的主要方法的最后一行不做任何事情,因为您没有分配该新类。无论如何,如上所述,您通常使用构建方法,而不是将构建器传递给构造函数
MyClass foo = MyClass.newBuilder()
.withBar("blah")
.build();
MyClass.newBuilder()
也可以由new MyClass.Builder()