1. 程式人生 > >Java與模式之建造者模式詳解

Java與模式之建造者模式詳解

建造模式是物件的建立模式。建造模式可以將一個產品的內部表象與產品的生成過程分割開來,從而可以使一個建造過程生成具有不同的內部表象的產品物件。

產品的內部表象

一個產品常有不同的組成成分作為產品的零件,這些零件有可能是物件,也有可能不是物件,它們通常又叫做產品的內部表象。不同的產品可以有不同的內部表象,也就是不同的零件。使用建造模式可以使客戶端不需要知道所生成的產品物件有哪些零件,每個產品的對應零件彼此有何不同,是怎麼樣建造出來的,以及怎麼樣組成產品。

物件性質的建造

       有些情況下,一個物件會有一些重要的性質,在它們沒有恰當的值之前,物件不能作為一個完整的產品使用。比如,一個電子郵件有收件人地址、發件人地址、主題、內容等部分,而最起碼的收件人地址得到賦值前,這個郵件是不能發出的。

       這個時候,此物件相當於一個有待建造的產品,而物件的這些性質相當於產品的零件,建造產品的過程就是建造零件的過程。由於建造零件的過程很複雜,因此,這些零件的建造過程往往被“外部化”到另一個成為建造者的物件裡,建造者物件返還給客戶端的是一個全部零件都建造完畢的產品物件。

建造模式利用一個導演者物件和具體建造者物件一個一個的建造出出所有的零件,從而建造出完整的產品物件。建造者模式將產品的結構和產品的零件建造過程對客戶端隱藏起來,把對建造過程進行指揮的責任和具體建造者零件的責任分割出來,達到責任劃分和封裝的目的。

建造者模式的結構


Ø  建造者(Builder)角色:給出一個抽象介面,以規範產品物件的各個組成成分的建造。一般而言,此介面獨立於應用程式的商業邏輯

。模式中直接建立產品物件的是具體建造者(ConcreteBuilder)角色。具體建造者類必須實現這個介面所要求的方法:一個是建造方法,另一個是結果返還方法。一般來說,產品所包含的零件數目與建造方法的數目相符。換言之,有多少零件,就有多少響應的建造方法。

Ø  具體建造者(Concrete Builder)角色:擔任這個角色的是與應用程式緊密相關的類,它們在應用程式呼叫下建立產品例項。這個角色主要完成的任務包括:

•      實現Builder角色提供的介面,一步一步完成建立產品例項的過程。

•      在建造過程完成後,提供產品的例項。

Ø  指導者(Director)角色:擔任這個角色的類呼叫具體建造者角色以建立產品物件

。導演者並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者物件。

Ø  產品(Product)角色:產品便是建造中的複雜物件。一般來說,一個系統中會有多於一個的產品類,而且這些產品類並不一定有共同的介面,而完全可以是不相關的。

指導者角色是與客戶端打交道的角色。導演者角色將客戶端建立產品的請求劃分為對各個零件的建造請求,再將這些請求委派給具體建造者角色。具體建造者角色是做具體建造工作的,但卻不為客戶端所知。

一般說來,每有一個產品類,就有一個對應的具體建造者類。這些產品應當有一樣數目的零件,而每有一個零件就應該在相應的建造者角色裡有一個建造方法

建造模式的實現

       在這個諸神造人的系統中,女媧本人扮演建造者的角色,她控制著造人的諸神:黃帝、上駢和桑林。與女媧傳土造人和舉繩造人的神話不同,眾神造人的神話是說人是一部分一部分的造出來的。黃帝創造了人的靈魂,上駢造出人的感官,桑林造出人的手臂。

抽象建造者角色:

public abstract class Builder {
	public abstract void buildPartOne();
	public abstract void buildPartTwo();	
	public abstract void buildPartThree();
	
	
	public abstract Product retrieveResult();
}

具體建造者角色:

public class ConcreteBuilder extends Builder {
	private Product product = new Product();

	@Override
	public void buildPartOne() {
		product.setPartOne("靈魂");	
		System.out.println("靈魂造好");
	}

	@Override
	public void buildPartTwo() {
		product.setPartTwo("感官");
		System.out.println("感官造好");
	}

	@Override
	public void buildPartThree() {
		product.setPartThree("耳目");
		System.out.println("耳目造好");
	}

	@Override
	public Product retrieveResult() {
		return product;
	}

	

}

導演角色
package builder;

public class Director {
	private Builder builder;
	
	public Director(Builder builder){
		this.builder = builder;
	}
	
	public  void construct() {
		builder.buildPartOne();
		builder.buildPartTwo();
		builder.buildPartThree();							
	}	
}

產品角色
public class Product {
	private String partOne; 
	private String partTwo; 
	private String partThree;
	
	@Override
	public String toString() {
		return "product:"+partOne+partTwo+partThree;
	}
	public String getPartOne() {
		return partOne;
	}
	public void setPartOne(String partOne) {
		this.partOne = partOne;
	}
	public String getPartTwo() {
		return partTwo;
	}
	public void setPartTwo(String partTwo) {
		this.partTwo = partTwo;
	}
	public String getPartThree() {
		return partThree;
	}
	public void setPartThree(String partThree) {
		this.partThree = partThree;
	}
}

客戶端


public class Client {
	public static void main(String[] args) {
		Builder builder = new ConcreteBuilder();
		Director diretor = new Director(builder);				
		diretor.construct();		
		System.out.println(builder.retrieveResult());
	}
}