Joh*_*n S 7 java model object effective-java
所以我一直在阅读一些有效的Java!本书最鼓舞人心的部分之一是Immutable Object/Builder部分,其中Bloch写的是关于"Builder" - 类,而不仅仅是POJO.
注意:我在这里谈论模型对象:例如文章或汽车.
这是我之前写这些对象的方式:
public class Car {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当您看到此设计在许多方面存在缺陷时,它需要可变性,您必须首先使用构造函数构造对象,然后设置名称.
当然,你现在可以使name
字段最终并将其用作构造函数中的参数,但是如果你有一个大对象包装例如一些SQL - Tables那么你将有一个丑陋的构造函数,如下所示:
public Car(int horsepowers, String name, String brand, int yearManufactured,
User owner, List<User> previousOwners) {
//Set the values
}
Run Code Online (Sandbox Code Playgroud)
这在创建对象时变得不可读,而这只是六个字段!
所以,布洛赫建议如下(具有不变性)
public class Car {
public static class Builder {
private String name;
public Builder setName(String name) {
this.name = name;
return this;
}
public Car build() {
reeturn new Car(this);
}
}
private final String name;
private Car(Builder builder) {
name = builder.name;
}
public String getName() {
return name;
}
}
//Construction example
Car car = new Car.Builder().setName("Speedy").build();
Run Code Online (Sandbox Code Playgroud)
现在这给了我们不变的感觉!如果你有一些不是原始或不可变的对象,只需将它们复制到Builder
setter中,然后在Car
getter中再次复制它们.
但它非常冗长,如果类足够小,我一直在使用构造函数参数.如果一个类需要一个可变字段,我只是让该字段可变,如果该类有足够的属性(> 4个东西).
另一个问题是当使用android并且该类具有例如a时Bitmap
,则必须返回实际的位图而不是复制它,因为这样性能相当昂贵.
我已经看到了很多这样的问题,但我似乎无法在这个问题上找到一个好的答案:这些设计是否有任何标准以及它们的设计如何?有什么好处/瑕疵?
提前致谢!
编辑:
问题是:
构造一个应该是不可变的对象模型的最佳方法是什么?A)少量字段和B)大量字段?如何处理上述Bitmap
问题和类似问题?某些字段是否可变?
抱歉模糊不清.
该设计模式一书是当前的阿尔法和欧米茄。然而,这不是新事物,但似乎它经过了时间的考验。
您可以阅读每种设计模式的详细实际示例,它们之间的关系,使用方法和时间以及对每种示例的详尽说明。当然包括了Builder模式。
关于回答您的问题,尽管他们当然没有权威性,但我可以提出我的观点。
我认为,如果字段数量很少,则可以使用构造函数。例如,如果使用checkstyle,它将在7个参数上发出警告。
但是,如果您确定要立即重构该类,或者必须扩展它,则我认为Builder模式会更好,因为它更易于重构。重构构造函数从来都不是一件好事。
如果您有7个以上的参数,我认为Builder会更好。我正在广泛从事的当前项目中一直在使用它。
请注意,通过使用Builder模式,您不会说“好吧,我是不可变的对象生成器”。您说“好的,我正在构建参数化对象”。因此,您的班级中有一组可变字段不是问题。但是,如果您将类命名为ImmutableFooDTO
,后来又添加了可变字段,则会引起混乱。
因此,如果存在一组必须不可变的字段,则将它们标记为final,并使用构造函数/生成器并为可变字段提供setter。