1. 程式人生 > 其它 >設計模式——Builder

設計模式——Builder

技術標籤:設計模式設計模式生成器builder

Builder的中文名:生成器

作用

GOF中的描述:將一個複雜物件的構建和它的表示分離,使得同樣的構建過程可以建立不同的標識。

描述的解釋:Builder,按名字理解是建造,那麼建造什麼呢?那造房子來說,房子的組成主要是磚頭、鋼筋、水泥。而且其建造的構建基本一致,先打地基,再修承重柱,接著是封牆面,一步步穩紮穩打。不同的可能是不同材料混合的比例、鋼筋的材質等等。於是,可以從中固化出一套造房子的基本步驟,即GOF中所說的複雜物件的構建;相對於不同材料的混合方法,即表示方法,進行分析。

  1. 主要目的:將一個個的元件,組合成一個可以使用的產品。比如拿零件組裝出一輛汽車。
  2. 元件的生成方法都集中在一個抽象類中
  3. 產品的產出由生產的“工廠”決定

優缺點

  1. 通過抽象介面,通過改變內在實現,但不影響外部使用;
  2. 工廠可以決定元件的組裝方式,來產出不同的產品;
  3. 和抽象工廠(Abstract Factory)一樣,對修改的開放性差,要對抽象介面增加新的方法,支援不友好;

結構

  • Builder負責產生元件的抽象方法;
  • Director負責產品的生產;
  • ConcreteBuilder負責對產品進位制實際的組裝;

例子

以上圖為例,Director指代MazeGame類,Builder指代MazeBuilder,ConcreteBuidler指代MazeBuilderStandard類,Product指代Maze類,即Maze為生產結束後返回的產品。

#pragma once

class Room {
public:
    Room(int n) { }
};
class Wall {};

class Door {
public:
    Door(Room* r1, Room* r2) {}
};

class Maze {
public:
    void AddRoom(Room* r1) {}
    Room* RoomNo(int n) { return nullptr; }
};

/
class EnhantedRoom : public Room {
public:
    EnhantedRoom(int n) : Room(n) {
    }
};

class DoorNeedingSpell : public Door {
public:
    DoorNeedingSpell(Room* r1, Room* r2) : Door(r1, r2) { }
};

class BombedWall : public Wall {};

class BombedRoom : public Room {
public:
    BombedRoom(int n) : Room(n) {}
};
#pragma once

#include "Maze.h"

class MazeBuilder
{
public:
	virtual void BuildeMaze() { }
	virtual void BuildeRoom(int n) { }
	virtual void BuildeDoor(int r1, int r2) {  }

	virtual Maze* GetMaze() { return nullptr; }

protected:
	MazeBuilder() {}
};

class MazeBuilderStandard : public MazeBuilder
{
public:
	virtual void BuildeMaze() {
		_currentMaze = new Maze;
	}

	virtual Maze* GetMaze() { return _currentMaze; }

	virtual void BuildeRoom(int n) {
		if (!_currentMaze->RoomNo(n))
		{
			Room* newRoom = new Room(n);
			_currentMaze->AddRoom(newRoom);

			// 設定room的屬性
		}
	}
	virtual void BuildeDoor(int n1, int n2) {
		Room* r1 = _currentMaze->RoomNo(n1);
		Room* r2 = _currentMaze->RoomNo(n2);
		Door* d = new Door(r1, r2);

		// 設定room的屬性
	}

public:
	MazeBuilderStandard() { 
		_currentMaze = 0;
	}

	Maze* _currentMaze;
};


#pragma once
#include "Maze.h"
#include "Builder.h"

class MazeGame {
public:
	MazeGame() {}
	Maze* CreateMaze(MazeBuilder& builder)
	{
		builder.BuildeMaze();

		builder.BuildeRoom(1);
		builder.BuildeRoom(2);
		builder.BuildeDoor(1, 2);

		return builder.GetMaze();
	}
};
#include "MazeGame.h"
#include "Builder.h"

int main()
{
	MazeGame game;

	MazeBuilderStandard builder;
	game.CreateMaze(builder); // director負責構件的過程

	Maze* maze = builder.GetMaze(); // 得到最終的產品

	return 1;
}

Github連結:https://github.com/potterhere/CS-note/tree/master/DesignPattern/CreateMode_Builder

相關模式

Abstract Factory。

抽象工廠模式和生成器模式很接近,都是基於了一個總的抽象基類,但兩者所側重的階段不同。抽象工廠更側重於與產品的結合情況,使在使用產品的過程中無感知。而生成器模式主要側重於產品的產生,只需負責得到最後的一個產品即可。

參考資料

1. 《設計模式:可複用面向物件軟體的基礎》 GOF

2.生成器——Youtube