描述
????建造模式是對(duì)象的創(chuàng)建模式。建造模式可以將一個(gè)產(chǎn)品的內(nèi)部表象與產(chǎn)品的生產(chǎn)過程分割開來,從而可以使一個(gè)建造過程生成具有不同的內(nèi)部表象的產(chǎn)品對(duì)象。
簡介

????建造者模式是將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
????一個(gè)產(chǎn)品常有不同的組成成分作為產(chǎn)品的零件,這些零件有可能是對(duì)象,也有可能不是對(duì)象,它們通常又叫做產(chǎn)品的內(nèi)部表象(internal representation)。不同的產(chǎn)品可以有不同的內(nèi)部表象,也就是不同的零件。使用建造模式可以使客戶端不需要知道所生成的產(chǎn)品有哪些零件,每個(gè)產(chǎn)品的對(duì)應(yīng)零件彼此有何不同,是怎么建造出來的,以及怎么組成產(chǎn)品。
角色
抽象建造者(Builder)角色:給出一個(gè)抽象接口,以規(guī)范產(chǎn)品對(duì)象的各個(gè)組成成分的建造。一般而言,此接口獨(dú)立于應(yīng)用程序的商業(yè)邏輯。模式中直接創(chuàng)建產(chǎn)品對(duì)象的是具體建造者 (ConcreteBuilder)角色。具體建造者類必須實(shí)現(xiàn)這個(gè)接口所要求的兩種方法:一種是建造方法(buildPartA和 buildPartB),另一種是返還結(jié)構(gòu)方法(retrieveResult)。一般來說,產(chǎn)品所包含的零件數(shù)目與建造方法的數(shù)目相符。換言之,有多少零件就有多少相應(yīng)的建造方法。
具體建造者(ConcreteBuilder)角色:擔(dān)任這個(gè)角色的是與應(yīng)用程序緊密相關(guān)的一些類,它們?cè)趹?yīng)用程序調(diào)用下創(chuàng)建產(chǎn)品的實(shí)例。這個(gè)角色要完成的任務(wù)包括:1.實(shí)現(xiàn)抽象建造者Builder所聲明的接口,給出一步一步地完成創(chuàng)建產(chǎn)品實(shí)例的操作。2.在建造過程完成后,提供產(chǎn)品的實(shí)例。
導(dǎo)演者(Director)角色:擔(dān)任這個(gè)角色的類調(diào)用具體建造者角色以創(chuàng)建產(chǎn)品對(duì)象。應(yīng)當(dāng)指出的是,導(dǎo)演者角色并沒有產(chǎn)品類的具體知識(shí),真正擁有產(chǎn)品類的具體知識(shí)的是具體建造者角色。
產(chǎn)品(Product)角色:產(chǎn)品便是建造中的復(fù)雜對(duì)象。一般來說,一個(gè)系統(tǒng)中會(huì)有多于一個(gè)的產(chǎn)品類,而且這些產(chǎn)品類并不一定有共同的接口,而完全可以是不相關(guān)聯(lián)的。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
產(chǎn)品的建造和表示分離,實(shí)現(xiàn)了解耦。
隱藏了產(chǎn)品的建造細(xì)節(jié),用戶只需關(guān)心產(chǎn)品的表示,而不需要了解是如何創(chuàng)建產(chǎn)品的。
體現(xiàn)了開閉原則,如上代碼所示,如果需要再生產(chǎn)其他共享單車,只需要再開一條生產(chǎn)線即可,不影響其他生產(chǎn)線的作業(yè)。
缺點(diǎn)
產(chǎn)品必須有共同點(diǎn),范圍有限制。
如內(nèi)部變化復(fù)雜,會(huì)有很多的建造類,難以維護(hù)。
使用場(chǎng)景
需要生成的產(chǎn)品對(duì)象有復(fù)雜的內(nèi)部結(jié)構(gòu),每一個(gè)內(nèi)部成分本身可以是對(duì)象,也可以僅僅是一個(gè)對(duì)象(即產(chǎn)品對(duì)象)的一個(gè)組成部分。
需要生成的產(chǎn)品對(duì)象的屬性相互依賴。建造模式可以強(qiáng)制實(shí)行一種分步驟進(jìn)行的建造過程,因此,如果產(chǎn)品對(duì)象的一個(gè)屬性必須在另一個(gè)屬性被賦值之后才可以被賦值,使用建造模式是一個(gè)很好的設(shè)計(jì)思想。
在對(duì)象創(chuàng)建過程中會(huì)使用到系統(tǒng)中的其他一些對(duì)象,這些對(duì)象在產(chǎn)品對(duì)象的創(chuàng)建過程中不易得到。
示例
???我們用制造自行車為例子講解建造者模式,自行車由車架、輪胎、腳踏等部件組成。自行車制造公司就是把這些零部件組裝起來。自行車制造公司的工程部門相當(dāng)于指揮者,生產(chǎn)部門相當(dāng)于建造者,當(dāng)今共享單車做的比較大的摩拜和ofo相當(dāng)于客戶,單車就是產(chǎn)品了。
/**
* 產(chǎn)品(Product)角色
* 單車產(chǎn)品
*/
public class Bike {
/**
* 輪胎
*/
private String tyre;
/**
* 車架
*/
private String frame;
/**
* GPS定位裝置
*/
private String gps;
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
public String getFrame() {
return frame;
}
public void setFrame(String frame) {
this.frame = frame;
}
public String getGps() {
return gps;
}
public void setGps(String gps) {
this.gps = gps;
}
@Override
public String toString() {
return "Bike{" +
"tyre='" + tyre + '\'' +
", frame='" + frame + '\'' +
", gps='" + gps + '\'' +
'}';
}
}
/**
* 抽象建造者(Builder)角色
* 自行車生產(chǎn)線接口
*/
public interface BikeBuilder {
/**
* 組裝輪胎
*/
void buildTyres();
/**
* 組裝車架
*/
void buildFrame();
/**
* 組裝GPS定位裝置
*/
void buildGPS();
/**
* 獲取自行車
*/
Bike getBike();
}
/**
* 具體建造者(ConcreteBuilder)角色
* 摩拜單車
*/
public class MoBikeBuilder implements BikeBuilder {
/**
* 單車對(duì)象
*/
private Bike bike;
public MoBikeBuilder(Bike bike) {
this.bike = bike;
}
@Override
public void buildTyres() {
bike.setTyre("橙色輪胎");
}
@Override
public void buildFrame() {
bike.setFrame("橙色車架");
}
@Override
public void buildGPS() {
bike.setGps("mobike定制版GPS定位裝置");
}
@Override
public Bike getBike() {
return bike;
}
}
/**
* 具體建造者(ConcreteBuilder)角色
* OfO單車
*/
public class OfoBikeBuilder implements BikeBuilder {
/**
* 單車對(duì)象
*/
private Bike bike;
@Override
public void buildTyres() {
bike.setTyre("黑色輪胎");
}
@Override
public void buildFrame() {
bike.setFrame("黃色車架");
}
@Override
public void buildGPS() {
bike.setGps("ofo定制版GPS定位裝置");
}
@Override
public Bike getBike() {
return bike;
}
}
/**
* 導(dǎo)演者(Director)角色
* 指導(dǎo)組裝單車
*/
public class EngineeringDepartment {
private BikeBuilder bikeBuilder;
/**
* 用戶告知指揮者想要什么樣的單車
*
* @param bikeBuilder
*/
public EngineeringDepartment(BikeBuilder bikeBuilder) {
this.bikeBuilder = bikeBuilder;
}
/**
* 指導(dǎo)組裝單車
*/
public void construct() {
bikeBuilder.buildTyres();
bikeBuilder.buildFrame();
bikeBuilder.buildGPS();
}
}
/**
* 測(cè)試類
*/
public class BuilderTest {
public static void main(String[] args) {
Bike bike = new Bike();
/**
* 創(chuàng)建摩拜單車
*/
BikeBuilder bikeBuilder = new MoBikeBuilder(bike);
EngineeringDepartment engineeringDepartment = new EngineeringDepartment(bikeBuilder);
/**
* 指導(dǎo)組裝單車
*/
engineeringDepartment.construct();
System.out.println(bike.toString());
}
}