一,定義
Builder模式是一種廣泛使用的設(shè)計(jì)模式,定義是:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
經(jīng)過演化,現(xiàn)在在Android中使用的是這個(gè)模式的一個(gè)變種。
二,經(jīng)典的Builder模式
經(jīng)典的Builder模式主要有四個(gè)參與者:
1.Product:被構(gòu)造的復(fù)雜對(duì)象,ConcreteBuilder用來創(chuàng)建該對(duì)象的內(nèi)部表示,并定義它的裝配過程。
2.Builder:抽象接口,用來定義創(chuàng)建Product對(duì)象的各個(gè)組成部件的操作。
3.ConcreteBuilder:Builder接口的具體實(shí)現(xiàn),可以定義多個(gè),是實(shí)際構(gòu)建Product對(duì)象的地方,同時(shí)會(huì)提供一個(gè)返回Product的接口。
4.Director:Builder接口的構(gòu)造者和使用者
例子:
首先是要?jiǎng)?chuàng)建的Product類:
public class? Product{
private String partOne;
private String partTwo;
public String getPartOne() {
return partOne;
}
public String getPartTwo() {
return partTwo;
}
public void setPartOne(String partOne)
{
this.partOne = partOne;
}
public void setPartTwo(String partTwo)
{
this.partTwo = partTwo;
}
}
Product類有兩個(gè)參數(shù)可設(shè)置
然后是Builder接口
public interface Builder {
public void buildPartOne();
public void buildPartTwo();
public Product getProduct();
}
然后實(shí)現(xiàn)Builder接口,創(chuàng)建一個(gè)ConcreteBuilder。
public class ConcreteBuilderA implements Builder {
private Product product;
@Override
public void buildPartOne() {
}
@Override
public void buildPartTwo() {
}
@Override
public Product getProduct() {
return product;
}
}
最后是Director類
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void builderProduct(){
this.builder.buildPartOne();
this.builder.buildPartTwo();
}
public Product getProduct(){
return this.builder.getProduct();
}
}
三,builder模式的變種
經(jīng)典的builder模式重點(diǎn)在于抽象創(chuàng)建的步驟,并通過調(diào)用不同的具體實(shí)現(xiàn)從而得到不同的結(jié)果,而變種的builder模式的目的在于減少對(duì)象的創(chuàng)建過程中引入的多個(gè)重載構(gòu)造函數(shù),可選參數(shù)以及setters過度使用導(dǎo)致的不必要的復(fù)雜性。
定義一個(gè)User類及其內(nèi)部類UserBuilder
public class User {
private final String mFirstName; //必選
private final String mLastName; //必選
private final String mGender; //可選
private final int mAge;//可選
private final String mPhoneNo;//可選
public User(UserBuilder builder){
mFirstName=builder.mFirstName;
mLastName=builder.mLastName;
mGender=builder.mGender;
mAge=builder.mAge;
mPhoneNo=builder.mPhoneNo;
}
public String getmFirstName() {
return mFirstName;
}
public String getmLastName() {
return mLastName;
}
public String getmGender() {
return mGender;
}
public int getmAge() {
return mAge;
}
public String getmPhoneNo() {
return mPhoneNo;
}
public static class UserBuilder{
private final String mFirstName;
private final String mLastName;
private String mGender;
private int mAge;
private String mPhoneNo;
public UserBuilder(String mFirstName, String mLastName) {
this.mFirstName = mFirstName;
this.mLastName = mLastName;
}
public UserBuilder gender(String mGender){
this.mGender=mGender;
return this;
}
public UserBuilder age(int age){
this.mAge=age;
return this;
}
public UserBuilder phone(String mPhoneNo){
this.mPhoneNo=mPhoneNo;
return this;
}
public User build(){
return new User(this);
}
}
}
上面代碼有幾個(gè)特點(diǎn):
1.User類的構(gòu)造函數(shù)是私有的,意味著調(diào)用者不能直接實(shí)例化這個(gè)類
2.User類是不可變的,所有必選屬性都是final的并且在構(gòu)造函數(shù)中設(shè)置;同時(shí)對(duì)屬性只提供getter函數(shù)。
3.UserBuilder的構(gòu)造函數(shù)只接受必選的屬性值作為參數(shù),并且只有必選的屬性值設(shè)置為final,以保證它們?cè)跇?gòu)造函數(shù)中設(shè)置。
使用方法;
public User getUser(){
return new User.UserBuilder("a","b")
.gender("male")
.age(30)
.phone("123")
.build();
}