生成器模式

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

適用性

在以下情況使用生成器模式:

  • 當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時;
  • 當構造過程必須允許被構造的對象有不同的表示時。

參與者

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

協作

客戶創建Director對象,並用它所想要的Builder對象進行配置。

  • 一旦產品部件被生成,導向器就會通知生成器。
  • 生成器處理導向器的請求,並將部件添加到該產品中。
  • 客戶從生成器中檢索產品。

範例

 /** "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
//設計模式:生成器模式
//Coder:  rollenc ( http://www.rollenc.com )
interface Builder {
	function buildPartA(); //创建部件A比如创建汽车车轮
	//创建部件B 比如创建汽车方向盘
	function buildPartB(); 
	//创建部件C 比如创建汽车发动机
	function buildPartC(); 

	//返回最后组装成品结果 (返回最后装配好的汽车)
	//成品的组装过程不在这里进行,而是转移到下面的Director类中进行.
	//从而实现了解耦过程和部件
	//return Product
	function getResult(); 
}

class Director {
	private $builder; 

	public function __construct($builder ) { 
		$this->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(); 

?>
#pragma once
#include<iostream>
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();
    cout<<product->ProductName<<endl;//"ProductA"
    delete creator;
    delete product;
    creator=new CreatorB;
    product=creator->CreateProduct();
    cout<<product->ProductName<<endl;//"ProductB"
    delete creator;
    delete product;
    return 0;
}

注意問題

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

效果

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

相關模式

抽象工廠模式與生成器相似,因為它也可以創建複雜對象。主要的區別是生成器模式着重於一步步構造一個複雜對象。而抽象工廠模式着重於多個系列的產品對象(簡單的或是複雜的)。生成器在最後的一步返回產品,而對於抽象工廠來說,產品是立即返回的。

組合模式通常是用生成器生成的。

參考

設計模式:可復用面向對象軟件的基礎

外部連結

軟件工程筆記庫[永久失效連結]