表象的產品對象。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
相關模式:思路和模板方法模式很像,模板方法是封裝算法流程,對某些細節,提供接口由子類修改,建造者模式更爲高層一點,將所有細節都交由子類實現。
建造者模式的使用情況:
以下情況應當使用建造者模式:
1、需要生成的產品對象有複雜的內部結構。
2、需要生成的產品對象的屬性相互依賴,建造者模式可以強迫生成順序。
3、 在對象創建過程中會使用到系統中的一些其它對象,這些對象在產品對象的創建過程中不易得到。
優缺點:
優點:1、建造者模式的使用使得產品內部表象可以獨立的變化,使客戶端不必知道產品內部組成細節。
2、每一個Builder都相對獨立,而與其它的Builder無關。
3、可以使對構造過程更加精細控制,以降低控制細節的風險。
4、將構建代碼和表示代碼分開。
缺點:1、由於其的變化點在於對象創建的細節,故其也難於分步驟構建的算法需求的變動,因爲其關注的是對象創建順序。
建造者模式一般適用於穩定的系統,比如說同樣是對人的描述,如果描述的是正常人,就可用,但是對於殘疾人,因爲系統不再穩定,再使用的話就無法滿足“開閉原則”了。
當要生產的一種產品具有相同的結構,並且每個構件的生產都很繁雜,就可以用Builder模式將具體構件的生產與整個成品的組裝分離開來。還是拿本文的代碼來舉例,生產一臺筆記本,筆記本的廠家不需要知道CPU怎麼生產的,不需要關心內存怎麼生產的,也不需要關心主板怎麼生產的等。當他在生產一臺筆記本的時候,只會說,我要一塊Intel的CPU,於是就有了CPU(至於Intel的CPU怎麼生產的他不關心,他只要一個CPu),他又說我要一塊金士頓內存,於是就有了金士頓內存,這樣直到他得到了所有的構件,然後他把這些構件組裝起來,組成一臺筆記本賣給客戶。這就是一個典型的Builder模式。下面是代碼:
/**
* CPU抽象類
*/
public abstract class CPU {
public abstract CPU getCPU();
}
/**
* Intel的cpu
*/
public class IntelCPU extends CPU {
public IntelCPU(){};
@Override
public CPU getCPU() {
// TODO Auto-generated method stub
return new IntelCPU();
}
public String toString(){
return " IntelCPU ";
}
}
/**
* AMD的cpu
*/
public class AMDCPU extends CPU {
public AMDCPU(){};
@Override
public CPU getCPU() {
// TODO Auto-generated method stub
return new AMDCPU();
}
public String toString(){
return " AMDCPU ";
}
}
/**
* 內存抽象類
*/
public abstract class Memory {
public abstract Memory getMemory();
}
/**
* 金士頓內存
*/
public class KingstonMemory extends Memory {
public KingstonMemory(){};
@Override
public Memory getMemory() {
return new KingstonMemory();
}
public String toString(){
return " KingstonMemory ";
}
}
/**
* 宇瞻內存
*/
public class ApacerMemory extends Memory {
public ApacerMemory(){};
@Override
public Memory getMemory() {
// TODO Auto-generated method stub
return new ApacerMemory();
}
public String toString(){
return " ApacerMemory ";
}
}
**
* 主板抽象類
*/
public abstract class Mainboard {
public abstract Mainboard getMainboard();
}
/**
* 華碩主板
*/
public class AsusMainboard extends Mainboard {
public AsusMainboard(){};
@Override
public Mainboard getMainboard() {
// TODO Auto-generated method stub
return new AsusMainboard();
}
public String toString(){
return " AsusMainboard ";
}
}
/**
* 技嘉主板
*/
public class GaMainboard extends Mainboard {
public GaMainboard(){}
@Override
public Mainboard getMainboard() {
return new GaMainboard();
};
public String toString(){
return " GaMainboard ";
}
}
/**
* 計算機所需組件
*/
public class Computer {
private CPU cpu;
private Memory memory;
private Mainboard mainboard;
public CPU getCpu() {
return cpu;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public Memory getMemory() {
return memory;
}
public void setMemory(Memory memory) {
this.memory = memory;
}
public Mainboard getMainboard() {
return mainboard;
}
public void setMainboard(Mainboard mainboard) {
this.mainboard = mainboard;
}
}
/**
* 計算機Builder
*/
public interface ComputerBuilder {
public void buildCPU();
public void buildMemory();
public void buildMainboard();
public Computer getComputer();
}
/**
* 聯想計算機Builder
*/
public class LenoveComputerBuilder implements ComputerBuilder {
private Computer lenoveComputer=null;
public LenoveComputerBuilder(){
lenoveComputer=new Computer();
}
@Override
public void buildCPU() {
lenoveComputer.setCpu(new IntelCPU());
}
@Override
public void buildMemory() {
lenoveComputer.setMemory(new KingstonMemory());
}
@Override
public void buildMainboard() {
lenoveComputer.setMainboard(new AsusMainboard());
}
@Override
public Computer getComputer() {
buildCPU();
buildMemory();
buildMainboard();
return lenoveComputer;
}
}
/**
* 惠普計算機Builder
*/
public class HPComputerBuilder implements ComputerBuilder {
private Computer HPComputer=null;
public HPComputerBuilder(){
HPComputer = new Computer();
}
@Override
public void buildCPU() {
HPComputer.setCpu(new AMDCPU());
}
@Override
public void buildMemory() {
HPComputer.setMemory(new ApacerMemory());
}
@Override
public void buildMainboard() {
HPComputer.setMainboard(new GaMainboard());
}
@Override
public Computer getComputer() {
buildCPU();
buildMemory();
buildMainboard();
return HPComputer;
}
}
public class Director {
private ComputerBuilder builder;
public Director(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
return builder.getComputer();
}
}
public class TestBuilder {
/**
* @param args
*/
public static void main(String[] args) {
Computer lenoveComputer,hpComputer;
ComputerBuilder lenoveComputerBuilder = new LenoveComputerBuilder();
ComputerBuilder hpComputerBuilder = new HPComputerBuilder();
Director director;
director = new Director(lenoveComputerBuilder);
lenoveComputer=director.construct();
director = new Director(hpComputerBuilder);
hpComputer=director.construct();
System.out.println("lenoveComputer is made by:"+lenoveComputer.getCpu()+lenoveComputer.getMemory()+lenoveComputer.getMainboard());
System.out.println("hpComputer is made by:"+hpComputer.getCpu()+hpComputer.getMemory()+hpComputer.getMainboard());
}
}
運行結果:
lenoveComputer is made by: IntelCPU KingstonMemory AsusMainboard
hpComputer is made by: AMDCPU ApacerMemory GaMainboard
註解:
在main函數裏面,director調用了builder裏面的getComputer()方法,getComputer()方法實際就是組裝的過程,getComputer()裏面的buildCPU();
buildMemory(); buildMainboard(); 就是在購買構件,而這些構件生產的具體過程放在了這些構件自身的類裏面,可以看到buildCPU()裏面有new一個對象,這就是在進行生產。這樣就達到了組裝和生產構件之間的分離。
最後,說說Builder模式和Factory模式之間區別的理解。Builder和Factory之間的區別就是組裝和生產之間的區別,Builder着重將組裝和構件的生產分離,Factory着重於優化生產的過程。本文的代碼實際上還可以進行重構,例如,在buildCPU()函數裏面,用到了new這個關鍵字,實際上可以將這個new換成工廠類,讓工廠類來生產CPU。換一種說法,就是Factory不進行組裝,Builder進行組裝,當Factory進行組裝的時候,它就變成Builder了。
下期預告,Prototype模式!