【发布时间】:2013-05-09 09:02:34
【问题描述】:
所以我一直在阅读一些Effective Java!书中最鼓舞人心的部分之一是不可变对象/构建器部分,布洛赫在其中写了“构建器”——类,而不仅仅是 POJO。
注意:我在这里谈论的是模型对象:例如 Article 或 Car。
这就是我之前写这些对象的方式:
public class Car {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
现在你看到这个设计在很多方面都有缺陷,它需要可变性,你必须先用构造函数构造对象,然后设置名称。
现在你当然可以将 name 字段设为 final 并将其用作构造函数中的参数,但是如果你有一个大对象包装例如一些 SQL - 表,那么你将有一个丑陋的构造函数,像这样:
public Car(int horsepowers, String name, String brand, int yearManufactured,
User owner, List<User> previousOwners) {
//Set the values
}
这在创建对象时变得不可读,而这只是六个字段!
因此,布洛赫提出以下建议(具有不变性)
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();
现在这给了我们不变性!如果您有一些对象不是原始的或不可变的,只需将它们复制到 Builder 的设置器中,然后再次将它们复制到 Car 的获取器中。
但它非常罗嗦,如果类足够小,我一直在使用构造函数参数。 如果一个类需要一个可变字段,如果该类有足够的属性(> 4 个),我只需将该字段设为可变。
另一个问题是,当使用 android 并且该类具有例如 Bitmap 时,您必须返回实际位图而不是复制它,因为这相当性能 - 昂贵。
我见过很多这样的问题,但我似乎无法找到一个很好的答案:这些设计是否有任何标准?它们的设计如何?有什么好处/缺点?
提前致谢!
编辑:
问题是:
构造一个应该是不可变的对象模型的最佳方法是什么?A)少量字段和B)大量字段?如何处理上述Bitmap 问题和类似问题?使某些字段可变?
抱歉含糊了。
【问题讨论】:
-
我认为
Builder的重点是当您处理具有一些必需和可选字段的不可变对象时。因为您将字段声明为final。所以它并不适用于所有设计。
标签: java object model effective-java