[英]What purpose of this code pattern?
我正在调试其他人的代码,而我只是不明白在Java中以这种方式进行编码的好处。
我不是Java Design Pattern专家,但是我想知道何时适用?
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
调用了Builder
类的构造函数。 通常不会执行此操作,因为将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();
我个人对这种模式的看法:
它鼓励创建和使用复杂的对象。 我更喜欢重构一个对象,该对象的生成器具有较小的组件。 仅通过构造函数,该对象就变得易于测试和创建。
构建器模式公开了所谓的Fluent API。 可以在每个行上进行单独的set调用,而不是在每个行上进行单独的set调用,而可以使用final生成方法来链接该类实例。 通常,在构建器对象上没有吸气剂。
该构造函数是副本构造函数的一种形式。 我猜想还有其他代码使用它来构建具有相同数据的对象的唯一实例。
main方法的最后一行不执行任何操作,因为您没有分配该新类。 如前所述,无论如何,您通常会使用构建方法,而不是将构建器传递给构造器
MyClass foo = MyClass.newBuilder()
.withBar("blah")
.build();
MyClass.newBuilder()
也可以替换为new MyClass.Builder()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.