生成器模式

生成器模式（英：Builder Pattern）是一種設計模式，又名：建造模式，是一種對象構建模式。它可以將複雜對象的建造過程抽象出來（抽象類別），使這個抽象過程的不同實現方法可以構造出不同表現（屬性）的對象。

**適用性**
在以下情況使用生成器模式：
*當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時；
*當構造過程必須允許被構造的對象有不同的表示時。

**參與者**
Builder
為創建一個Product對象的各個部件指定抽象接口。
*ConcreteBuilder
實現Builder的接口以構造和裝配該產品的各個部件。
定義並明確它所創建的表示。
提供一個檢索產品的接口
*Director
構造一個使用Builder接口的對象。
*Product
表示被構造的複雜對象。ConcreateBuilder創建該產品的內部表示並定義它的裝配過程。
包含定義組成部件的類，包括將這些部件裝配成最終產品的接口。

**協作**
客戶創建Director對象，並用它所想要的Builder對象進行配置。
*一旦產品部件被生成，導向器就會通知生成器。
*生成器處理導向器的請求，並將部件添加到該產品中。
*客戶從生成器中檢索產品。

**範例**

**Java**
/** "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";

public void setDough (String dough)     { this.dough = dough; }
public void setSauce (String sauce)     { this.sauce = sauce; }
public void setTopping (String topping) { this.topping = topping; }
}


/** "Abstract Builder" */
abstract class PizzaBuilder {
protected Pizza pizza;

public Pizza getPizza() { return pizza; }
public void createNewPizzaProduct() { pizza = new Pizza(); }

public abstract void buildDough();
public abstract void buildSauce();
public abstract void buildTopping();
}

/** "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough()   { pizza.setDough("cross"); }
public void buildSauce()   { pizza.setSauce("mild"); }
public void buildTopping() { pizza.setTopping("ham+pineapple"); }
}

/** "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough()   { pizza.setDough("pan baked"); }
public void buildSauce()   { pizza.setSauce("hot"); }
public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
}


/** "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;

public void setPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }

public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}

/** A customer ordering a pizza. */
class BuilderExample {
public static void main(String args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiianPizzabuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzabuilder = new SpicyPizzaBuilder();

waiter.setPizzaBuilder ( hawaiianPizzabuilder );
waiter.constructPizza();

Pizza pizza = waiter.getPizza();
}
}

**PHP**
builder = $builder; 
	} 
	// 將部件partA partB partC最後組成複雜對象
	//這裡是將車輪 方向盤和發動機組裝成汽車的過程
	public function construct() {
		$this->builder->buildPartA();
		$this->builder->buildPartB();
		$this->builder->buildPartC();
	}
}
class ConcreteBuilder implements Builder {
	public $partA, $partB, $partC;
	public function buildPartA() {
		echo 'partA is builded' . "\n";
	}
	public function buildPartB() {
		echo 'partB is builded' . "\n";
	}
	public function buildPartC() {
		echo 'partC is builded' . "\n";
	}
	public function getResult () {
		echo 'Return product.' . "\n";
		return 1;
	}
}
$builder = new ConcreteBuilder();
$director = new Director( $builder ); 
$director->construct(); 
$product = $builder->getResult(); 
?>

**C++**
#pragma once
#include
using namespace std;
class Product{
public:
string ProductName;
};
class ProductA: public Product{
public:
inline ProductA(void): ProductName("ProductA"){}
};
class ProductB:public Product{
public:
inline ProductB(void): ProductName("ProductB"){}
}
class Creator{
public:
inline Product *CreateProduct(void){
return DoCreateProduct();
}
protected:
virtual Product *DoCreateProduct(void)=0;
};
class CreatorA: public Creator{
public:
inline Product *DoCreateProduct(void)override{
return new ProductA;
}
};
class CreatorB: public Creator{
public:
inline Product *DoCreateProduct(void)override{
return new ProductB;
}
};
int main(int argc, char **argv){
Creator *creator=new CreatorA;
Product *product=creator->CreateProduct();
coutProductNameCreateProduct();
coutProductName

**注意問題**
裝配和構造接口
生成器逐步的構造它們的產品。因此生成器介面必須足夠普遍，以便為各種類型的具體生成器構造產品。
*沒有抽象類
通常情況下，由具體生成器生成的產品，它們的表示相差是如此之大以至於給不同的產品以公共父類沒有太大意思。
*在生成器中預設的方法為空
定義為空方法可以使客戶只重定義他們所感興趣的操作。

**效果**
它使你可以改變一個產品的內部表示
*它將構造代碼和表示代碼分開
*它使你可對構造過程進行更精細的控制

**相關模式**
抽象工廠模式與生成器相似，因為它也可以創建複雜對象。主要的區別是生成器模式著重於一步步構造一個複雜對象。而抽象工廠模式著重於多個系列的產品對象（簡單的或是複雜的）。生成器在最後的一步返回產品，而對於抽象工廠來說，產品是立即返回的。
組合模式通常是用生成器生成的。

**參考**
設計模式：可複用面向對象軟件的基礎

**外部連結**
軟件工程筆記庫fix-attempted=yes