一、简述
在设计模式中对Builder Pattern的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成。在实际的开发过程中,哪些地方适合用到Builder Pattern呢?其中使用Builder Pattern来替代多参数构造函数是一个比较好的实践法则。
我们常常会面临编写一个这样的实现类(假设类名叫DoContact),这个类拥有多个构造函数:
DoContact(String name);
DoContact(String name, int age);
DoContact(String name, int age, String address);
DoContact(String name, int age, String address, int cardID);
这样一系列的构造函数主要目的就是为了提供更多的客户调用选择,以处理不同的构造请求。这种方法很常见,也很有效力,但是它的缺点也很多。类的作者不得不书写多种参数组合的构造函数,而且其中还需要设置默认参数值,这是一个需要细心而又枯燥的工作。其次,这样的构造函数灵活性也不高,而且在调用时你不得不提供一些没有意义的参数值,例如,DoDoContact("Ace", -1, "SH"),显然年龄为负数没有意义,但是又不的不这样做,以符合Java的规范。如果这样的代码发布后,后面的维护者就会很头痛,因为他根本不知道这个-1是什么含义。对于这样的情况,就非常适合使用Builder Pattern。Builder Pattern的要点就是通过一个代理来完成对象的构建过程。这个代理职责就是完成构建的各个步骤,同时它也是易扩展的。下面是改写自Effective Java里面的一段代码:
public class DoContact {
private final int age;
private final int safeID;
private final String name;
private final String address;
public int getAge() {
return age;
}
public int getSafeID() {
return safeID;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public static class Builder {
private int age = 0;
private int safeID = 0;
private String name = null;
private String address = null;
// 构建的步骤
public Builder(String name) {
this.name = name;
}
public Builder age(int val) {
age = val;
return this;
}
public Builder safeID(int val) {
safeID = val;
return this;
}
public Builder address(String val) {
address = val;
return this;
}
// 构建,返回一个新对象
public DoContact build() {
return new DoContact(this);
}
}
private DoContact(Builder b) {
age = b.age;
safeID = b.safeID;
name = b.name;
address = b.address;
}
}
最终,调用者可以很灵活的去构建这个对象:
public class kfd {
public static void main(String[] args) {
DoContact object = new DoContact.Builder("MChopin").age(18)
.address("shanghai").build();
System.out.println("name=" + object.getName() + " age=" + object.getAge()
+ " address=" + object.getAddress());
}
}
网友评论