JAVA設計模式之生成器模式

1. 什麼是生成器模式?

《Head First設計模式》中定義:封裝一個產品的構造過程,並允許按步驟構造。


生成器模式(Builder Pattern)將一個複雜對象構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。生成器模式是對象創建型模式,又叫建造者模式


生成器模式針對的是複雜對象的創建。它可以將複雜對象的建造過程抽象出來,使這個抽象過程的不同實現方法可以構造不同表現(屬性)的對象。


舉個例子加深理解:

比如我們要去法拉利私人定製一款汽車,我們只需要向服務商提需求,然後服務商就會協調生產車間生產汽車。定製的汽車就是一個複雜的對象,其中包含空調系統、電子系統。動力系統等,而每一個子系統的生產都是複雜且非常耗時的。如果全部工作都交給一個車間來生產的話(傳統創建對象),可能等我老了這個車還沒造出來。如果將生產過程各自分工(創建過程抽象出來),然後由一個協調部門負責組裝的話,這樣汽車建造速度將大大提高,而且私人定製也比較容易(想怎麼組裝就怎麼組裝),裝上普通動力系統的就是法拉利轎車,裝上強勁動力系統就是法拉利跑車(不同的表現)。這個協調部門就是Director角色。

 

2. 角色

 

圖片來源於網絡

抽象建造者(Builder):可以是接口也可以是抽象類。爲創建產品Product對象的各個組件指定抽象方法。一般有兩類方法,一類是創建複雜對象的各個組件(buildPartA、buildPartB...)和另一類返回創建的複雜對象(getResult)。

具體建造者(ConcreteBuilder):Builder的具體實現類,可以有多個,每一個提供複雜對象各個組件的一種創建和裝配方法,最終返回創建好的複雜對象。

產品角色(Product):它是被構建的複雜對象,包含多個組成部件,具體建造者創建該產品的內部表示並定義它的裝配過程

指揮者角色(Director):Director負責安排複雜對象Product的建造次序。Director和Builder存在關聯關係,通過construct方法調用Builder中的創建方法完成複雜對象的創建。客戶端只需要和Director聯繫。

3. 優點

(1)客戶端不需要知道複雜對象的創建細節,將對象和創建過程解耦,使相同的創建過程可以創建不同的對象。

(2)每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可創建不同的產品對象。由於指揮者類針對抽象建造者編程,增加新的具體建造者無須修改原有代碼,系統擴展方便,符合“開閉原則”。

(3)可以更加精細地控制產品的創建過程。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也更方便使用程序來控制創建過程。

4. 缺點

(1)使用生成器模式必須要求Product類具有相似的結構,如果差異性太大就無法使用該模式,因此具有一定的侷限性。

(2)將創建過程抽象出來會造成類文件增加。

5. 使用場景

(1)要生成的產品對象有複雜的內部結構,包含多個成員屬性。

(2)將創建過程分離開,使相同的創建過程能創建不同的產品對象。

(3)產品對象內部組件之間存在相互依賴,且組件創建具有一定的順序。

6. 示例代碼

(1)抽象建造者類

/**
 *抽象建造者 
 */
public abstract class AbstractCarBuilder {
	//產品的引用
	protected Car car;

	public AbstractCarBuilder() {
		this.car=new Car();
	}

	public abstract void buildAcSystem();
	public abstract void buildPowerSystem();
	public abstract void buildElectronicSystem();
	
	public Car getCar(){
		return car;
	}
	
}

 

(2)具體建造者類

/**
 * 普通汽車建造者
 */
public class LittleCarBuilder extends AbstractCarBuilder {

	@Override
	public void buildAcSystem() {
		this.car.setAcSystem("海爾空調系統");
	}

	@Override
	public void buildPowerSystem() {
		this.car.setPowerSystem("1.6自然吸氣系統");
	}

	@Override
	public void buildElectronicSystem() {
		this.car.setElectronicSystem("華爲電子系統");
	}
}

/**
 * 跑車建造者
 */
public class SportsCarBuilder extends AbstractCarBuilder {

	@Override
	public void buildAcSystem() {
		this.car.setAcSystem("格力空調系統");
	}

	@Override
	public void buildPowerSystem() {
		this.car.setPowerSystem("4.0T渦輪增壓系統");
	}

	@Override
	public void buildElectronicSystem() {
		this.car.setElectronicSystem("西門子電子系統");
	}
}

(3)產品類

/**
 *產品類
 *其中可能存在許多創建過程比較複雜的其他對象 
 */
public class Car {
	//空調系統組件(可以是一個對象)
	private String acSystem;
	//動力系統組件
	private String powerSystem;
	//電子系統組件
	private String electronicSystem;
	public String getAcSystem() {
		return acSystem;
	}
	public void setAcSystem(String acSystem) {
		this.acSystem = acSystem;
	}
	public String getPowerSystem() {
		return powerSystem;
	}
	public void setPowerSystem(String powerSystem) {
		this.powerSystem = powerSystem;
	}
	public String getElectronicSystem() {
		return electronicSystem;
	}
	public void setElectronicSystem(String electronicSystem) {
		this.electronicSystem = electronicSystem;
	}
	@Override
	public String toString() {
		return "Car [acSystem=" + acSystem + ", powerSystem=" + powerSystem + ", electronicSystem=" + electronicSystem
				+ "]";
	}
}

(4)指揮者類

/**
 *car建造指揮者 
 */
public class CarDirector {
	private AbstractCarBuilder acb;
	public CarDirector(AbstractCarBuilder acb) {
		this.acb=acb;
	}
	public void setAcb(AbstractCarBuilder acb) {
		this.acb = acb;
	}
	
	public Car constructCar(){
		//此處可以規定組件創建順序
		acb.buildAcSystem();
		acb.buildElectronicSystem();
		acb.buildPowerSystem();
		return acb.getCar();
	}
}

(5)測試

public class Client {

	public static void main(String[] args) {
		CarDirector director=new CarDirector(new SportsCarBuilder());
		Car car1=director.constructCar();
		System.out.println(car1.toString());
		
		System.out.println("---------------");
		
		director.setAcb(new LittleCarBuilder());
		Car car2=director.constructCar();
		System.out.println(car2.toString());
	}
}

(6)測試結果

Car [acSystem=格力空調系統, powerSystem=4.0T渦輪增壓系統, electronicSystem=西門子電子系統]
---------------
Car [acSystem=海爾空調系統, powerSystem=1.6自然吸氣系統, electronicSystem=華爲電子系統]


7. 生成器模式和工廠模式的對比

 

圖片來源於網絡


【四川樂山程序員聯盟,歡迎大家加羣相互交流學習5 7 1 8 1 4 7 4 3】

發佈了41 篇原創文章 · 獲贊 63 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章