我最近一直在与一个研究小组一起研究设计模式,并且逐渐了解到构建器模式对于创建由许多(可能是可选的)部分组成的复杂对象非常有用。
然而,建造者是否在某个时刻做得太多了呢?假设我们有一个包含许多不同对象组合的类,是否有另一种模式可能更适合该类,而不是制作数十个不同的构建器?是否可以通过不制作完全特定的构建器来减少所需的构建器数量?
我和我的研究小组不断回顾的例子是汽车制造商,例如汽车公司的网站。任何汽车公司都有数十辆汽车,每辆汽车都有许多不同的功能、颜色、附加功能等。按照我的理解,您的构建器应该特定于您正在制作的确切对象,因此将构建器模式应用于此示例将产生数百个类似于“RedSUVWithSunroofBuilder”、“BlueSUVWithSunroofBuilder”、“RedSUVBuilder”等的构建器。
使用构建器模式时,是否有任何原因无法传递其中一些值来减少需要创建的构建器的数量?例如,代替 RedSUVWithSunroofBuilder 或 BlueSUVWithSunroofBuilder,执行 SUVWithSunroofBuilder("Red") 和 SUVWithSunroofBuilder("Blue") 是否仍然适合构建器模式,或者这更适合不同的模式?
构建器模式当然是任意的,如果它过于复杂,那么它就过于复杂,您可能需要考虑使用不同的方式来创建对象,例如工厂模式 http://en.wikipedia.org/wiki/Factory_pattern。我认为构建器模式在一些场景中表现出色:
- Creating objects that have several valid configurations
- Creating immutable objects where not all required data can be supplied up front
- 对于一个很好的例子,请查看番石榴不可变集合构建器ImmutableSet.Builder http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html
以下是如何实施汽车制造商的一个示例:
public class Car {
private final boolean hasSunroof;
private final Color color;
private final int horsePower;
private final String modelName;
private Car(Color color, int horsePower, String modelName, boolean hasSunroof) {
this.color = color;
this.horsePower = horsePower;
this.hasSunroof = hasSunroof;
this.modelName = modelName;
}
public static Builder builder(Color color, int horsePower) {
return new Builder(color, horsePower);
}
public static class Builder {
private final Color color;
private final int horsePower;
private boolean hasSunroof;
private String modelName = "unknown";
public Builder(Color color, int horsePower) {
this.color = color;
this.horsePower = horsePower;
}
public Builder withSunroof() {
hasSunroof = true;
return this;
}
public Builder modelName(String modelName) {
this.modelName = modelName;
return this;
}
public Car createCar() {
return new Car(color, horsePower, modelName, hasSunroof);
}
}
}
Builder 不一定是嵌套类,但它确实允许您向可能滥用您的 API 的人隐藏您的构造函数。另请注意,所需的最低参数甚至必须提供才能创建构建器。您可以像这样使用这个构建器:
Car car = Car.builder(Color.WHITE, 500).withSunroof().modelName("Mustang").createCar();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)