設計模式之—建造者模式(Builder)-Java實現

Builder模式,將產品的內部表象和產品的生成過程分割開來,從而使一個建造過程生成具有不同的內部

表象的產品對象。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示

相關模式:思路和模板方法模式很像,模板方法是封裝算法流程,對某些細節,提供接口由子類修改,建造者模式更爲高層一點,將所有細節都交由子類實現。

建造者模式的使用情況:

以下情況應當使用建造者模式:

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模式!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章