在設計模式中對Builder模式的定義是用於構建複雜對象的一種模式,所構建的對象每每須要多步初始化或賦值才能完成。那麼,在實際的開發過程當中,咱們哪些地方適合用到Builder模式呢?其中使用Builder模式來替代多參數構造函數是一個比較好的實踐法則。java
咱們經常會面臨編寫一個這樣的實現類(假設類名叫DoDoContact),這個類擁有多個構造函數,設計模式
DoDoContact(String name);數組
DoDoContact(String name, int age);函數
DoDoContact(String name, int age, String address);post
DoDoContact(String name, int age, String address, int cardID);ui
這樣一系列的構造函數主要目的就是爲了提供更多的客戶調用選擇,以處理不一樣的構造請求。這種方法很常見,也頗有效力,可是它的缺點也不少。類的做者不得不書寫多種參數組合的構造函數,並且其中還須要設置默認參數值,這是一個須要細心而又枯燥的工做。其次,這樣的構造函數靈活性也不高,並且在調用時你不得不提供一些沒有意義的參數值,例如,DoDoContact("Ace", -1, "SH"),顯然年齡爲負數沒有意義,可是你又不的不這樣作,得以符合Java的規範。若是這樣的代碼發佈後,後面的維護者就會很頭痛,由於他根本不知道這個-1是什麼含義。對於這樣的狀況,就很是適合使用Builder模式。Builder模式的要點就是經過一個代理來完成對象的構建過程。這個代理職責就是完成構建的各個步驟,同時它也是易擴展的。下面是改寫自Effective Java裏面的一段代碼:this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
class
DoDoContact {
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
;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// 構建的步驟
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
DoDoContact build() {
// 構建,返回一個新對象
return
new
DoDoContact(
this
);
}
}
private
DoDoContact(Builder b) {
age = b.age;
safeID = b.safeID;
name = b.name;
address = b.address;
}
}
|
最終,客戶程序能夠很靈活的去構建這個對象。spa
1
2
3
4
|
DoDoContact ddc =
new
DoDoContact.Builder(
"Ace"
).age(
10
)
.address(
"beijing"
).build();
System.out.println(
"name="
+ ddc.getName() +
"age ="
+ ddc.getAge()
+
"address"
+ ddc.getAddress());
|