1、初識建造者模式
建造者模式屬于創(chuàng)建型模式碑宴。比如說:樓房是千差萬別的梗肝,樓房的外形颁糟,層數(shù),內(nèi)部房間的數(shù)量喉悴,房間的裝飾都不一樣棱貌。但是對于建造者來說,抽象出來的建筑流程是確定的箕肃。因為建筑一座樓房婚脱,都可以歸納為幾個步驟:1打樁、2建地基勺像、3搭框架障贸、4內(nèi)部建設。同理吟宦,建造者設計模式也是基于這樣的概念而生的篮洁,這個設計模式用來解決什么樣的情況呢:即流程不變,但每個流程實現(xiàn)的具體細節(jié)是會變化的殃姓。這樣的情況袁波,可以考慮使用建造者。就像蓋房子蜗侈,4個流程都必須有篷牌,但每個流程各自的實現(xiàn)細節(jié),各個房子各有不同宛篇。建造者模式的好處就是保證了流程不會變化娃磺,即流程不會增加也不會遺漏,也不會產(chǎn)生流程次序的錯誤叫倍。而建造者模式偷卧,保證了流程的確定性,而流程內(nèi)部的實現(xiàn)細節(jié)吆倦,是可繼承擴展的听诸。從根源上解決了流程不規(guī)范的問題。
擼代碼的時候蚕泽,如果你遇到一個需要把控流程晌梨,但流程中的實現(xiàn)細節(jié)各有許多的方式,你可以采用建造者模式须妻。用一個director類把控流程仔蝌,而用許多不同的builder去建造流程中的細節(jié)并產(chǎn)生產(chǎn)品。這樣荒吏,生產(chǎn)出來的產(chǎn)品基本是不會出問題的敛惊。因為流程把控好了。你可以有多個builder去負責建造生產(chǎn)產(chǎn)品绰更,而讓director去把控流程瞧挤。如果有新的產(chǎn)品锡宋,但是流程一致,你可以再擴張出一個builder來特恬。這樣执俩,你看,建造者模式是不是很符合OCP原則呢癌刽。
2役首、建造者模式的概念
將一個復雜的對象的構建與它的表示分離,使得同樣的構建過程可以有不同的表示妒穴。
大概的意思是說:一套的構建過程可以有不同的產(chǎn)品(表示)出來宋税。這些產(chǎn)品(表示)都按照這一套的構建過程被生產(chǎn)出來摊崭。
建造者模式通常包括以下這幾個角色:
Builder:給出一個抽象接口讼油,規(guī)范建造者對于生產(chǎn)的產(chǎn)品的各個組成部分的建造。這個接口只是定一個規(guī)范呢簸,不涉及具體的建造矮台,具體的建造讓繼承于它的子類(ConcreteBuilder)去實現(xiàn)
ConcreteBuilder:實現(xiàn)builder接口,針對不同的商業(yè)邏輯根时,具體化各對象部分的建造瘦赫,最后返回一個建造好的產(chǎn)品。實現(xiàn)抽象類的所有未實現(xiàn)的方法蛤迎,具體來說一般是兩項任務:組建產(chǎn)品确虱;返回組建好的產(chǎn)品。
Director:導演(負責人)替裆,顧名思義校辩,負責規(guī)范流程之用。在指導中不涉及產(chǎn)品的創(chuàng)建辆童,只負責保證復雜對象各部分被創(chuàng)建或按某種順序創(chuàng)建宜咒。導演類一般不與產(chǎn)品類發(fā)生依賴關系,與導演類直接交互的是建造者類把鉴。一般來說故黑,導演類被用來封裝程序中易變的部分。
Product:復雜對象庭砍。
建造者模式的UML圖(通過圖形來串聯(lián)自己所學的知識是非常高效的學習方式之一)
3场晶、一個建造者的實例。
汽車的構造當中怠缸,包括汽車品牌诗轻、型號、價格凯旭、產(chǎn)地等等概耻。
復雜對象Product
/**
* 復雜對象Product,這里是汽車
* @author Administrator
*
*/
public class Car {
private String name; //汽車品牌
private String type; //具體的型號
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
抽象的Builder:
/**
* 抽象的構造者
* @author Administrator
*
*/
public interface Builder {
/**
* 一般包含2個部分:1使套、抽象的建造方法;2:返回建造好的復雜對象
* @param name
*/
void buildName(String name);
void buildType(String type);
Car build();
}
具體的建造者
/**
* 具體的構建者
* @author Administrator
*
*/
public class ConstractBuilder implements Builder{
Car car = new Car();
@Override
public void buildName(String name) {
car.setName(name);
}
@Override
public void buildType(String type) {
car.setType(type);
}
@Override
public Car build() {
return car;
}
}
導演鞠柄,負責流程規(guī)范侦高,在導演類中可以注入建造者對象。
/**
* 導演(負責人)負責流程規(guī)范厌杜,
* @author Administrator
*
*/
public class Director {
public Car buildCar1(){
ConstractBuilder builder = new ConstractBuilder();
builder.buildName("寶馬");
builder.buildType("x6");
return builder.build();
}
public Car buildCar2(){
ConstractBuilder builder = new ConstractBuilder();
builder.buildName("奔馳");
builder.buildType("c200");
return builder.build();
}
}
** 客戶端調(diào)用**
public class Client {
public static void main(String[] args) {
Director director = new Director(); //創(chuàng)建導演類
//構造對象
Car car1 = director.buildCar1();
Car car2 = director.buildCar2();
System.out.println("car1 name:"+car1.getName()+" type:"+car1.getType());
System.out.println("car2 name:"+car2.getName()+" type:"+car2.getType());
}
}
** 4奉呛、使用建造者模式的好處**
- 使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細節(jié)。
- 具體的建造者類之間是相互獨立的夯尽,對系統(tǒng)的擴展非常有利瞧壮。
- 由于具體的建造者是獨立的,因此可以對建造過程逐步細化匙握,而不對其他的模塊產(chǎn)生任何影響咆槽。
5、使用建造者模式的場合
- 創(chuàng)建一些復雜的對象時圈纺,這些對象的內(nèi)部組成構件間的建造順序是穩(wěn)定的秦忿,但是對象的內(nèi)部組成構件面臨著復雜的變化
- 要創(chuàng)建的復雜對象的算法,獨立于該對象的組成部分蛾娶,也獨立于組成部分的裝配方法時灯谣。