為什么使用Builder模式
1、傳統(tǒng)的創(chuàng)建對(duì)象可以使用構(gòu)造器創(chuàng)建,但是當(dāng)我們調(diào)用構(gòu)造器時(shí)通常需要許多你不想要設(shè)置的參數(shù),但是又不得不為它們傳值。這個(gè)時(shí)候如果我們使用重疊構(gòu)造器可行,但是當(dāng)有許多參數(shù)的時(shí)候,客戶端的代碼就會(huì)非常難寫,并且很難閱讀。
重疊構(gòu)造器代碼如下
public class BuilderPerson {
//必選參數(shù)
private final String name;
private final int age;
private final int height;
private final int weight;
//可選參數(shù)
private final boolean isMarraying;
private final boolean isHasChildren;
public BuilderPerson(String name, int age) {
this(name,age,0);
}
public BuilderPerson(String name, int age, int height) {
this(name,age,height,0);
}
public BuilderPerson(String name, int age, int height, int weight) {
this(name,age,height,weight,false);
}
public BuilderPerson(String name, int age, int height, int weight, boolean isMarraying) {
this(name, age,height,weight,isMarraying,false);
}
public BuilderPerson(String name, int age, int height, int weight, boolean isMarraying, boolean isHasChildren) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
this.isMarraying = isMarraying;
this.isHasChildren = isHasChildren;
}
}
2、當(dāng)遇到許多構(gòu)造器參數(shù)的時(shí)候,還有第二中代替的辦法,即使用JavaBean模式,在這種模式下,調(diào)用一個(gè)無參的構(gòu)造器來創(chuàng)建對(duì)象,然后調(diào)用setter方法來設(shè)置每個(gè)必要的參數(shù),以及每個(gè)相關(guān)的可選參數(shù)。
JavaBean代碼如下
public class BuilderPerson {
//必選參數(shù)
private String name;
private int age;
private int height;
private int weight;
//可選參數(shù)
private boolean isMarraying;
private boolean isHasChildren;
public BuilderPerson() {
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setHeight(int height) {
this.height = height;
}
public void setWeight(int weight) {
this.weight = weight;
}
public void setMarraying(boolean marraying) {
isMarraying = marraying;
}
public void setHasChildren(boolean hasChildren) {
isHasChildren = hasChildren;
}
}
但是JavaBean模式自身有著嚴(yán)重的缺點(diǎn),會(huì)導(dǎo)致類處于不一致(你new了Test類的兩個(gè)實(shí)例,一個(gè)只set了A屬性,一個(gè)只設(shè)置了B屬性,這兩個(gè)實(shí)例不一致,你不能保證通過該類的同一個(gè)構(gòu)造器保證構(gòu)造出來的對(duì)象是屬性相同的。)的狀態(tài)。
這時(shí)就出現(xiàn)了第三種替代的方法既能像重疊構(gòu)造器那樣的安全性,也能保證代碼的可讀性即Builder模式。
代碼如下
public static class Builder{
//必選參數(shù)
private String name;
private int age;
private int height;
private int weight;
//可選參數(shù)
private final boolean isMarraying;
private final boolean isHasChildren;
public Builder(boolean isMarraying, boolean isHasChildren) {
this.isMarraying = isMarraying;
this.isHasChildren = isHasChildren;
}
public Builder name(String name) {
name = name;
return this;
}
public Builder age(int age) {
age = age;
return this;
}
public Builder height(int height) {
height = height;
return this;
}
public Builder weight(int weight) {
weight = weight;
return this;
}
public BuilderPerson builderPerson() {
return new BuilderPerson(this);
}
}
}
調(diào)用如下
BuilderPerson person = new BuilderPerson.Builder(false,false).
name("張三").age(20).height(180).weight(120).buildPerson();
總結(jié)
簡(jiǎn)而言之,如果類的構(gòu)造器或者靜態(tài)工廠中具有多個(gè)參數(shù),設(shè)計(jì)這種類時(shí),Builder模式就是種不錯(cuò)的選擇,特別是當(dāng)大多數(shù)參數(shù)都是可選的時(shí)候,與使用傳統(tǒng)的重疊構(gòu)造器模式相比,使用Builder模式的客戶端代碼將更易于閱讀和編寫,構(gòu)建器也比JavaBeans更加安全。