設計模式——Builder
阿新 • • 發佈:2020-12-13
Builder的中文名:生成器
作用
GOF中的描述:將一個複雜物件的構建和它的表示分離,使得同樣的構建過程可以建立不同的標識。
描述的解釋:Builder,按名字理解是建造,那麼建造什麼呢?那造房子來說,房子的組成主要是磚頭、鋼筋、水泥。而且其建造的構建基本一致,先打地基,再修承重柱,接著是封牆面,一步步穩紮穩打。不同的可能是不同材料混合的比例、鋼筋的材質等等。於是,可以從中固化出一套造房子的基本步驟,即GOF中所說的複雜物件的構建;相對於不同材料的混合方法,即表示方法,進行分析。
- 主要目的:將一個個的元件,組合成一個可以使用的產品。比如拿零件組裝出一輛汽車。
- 元件的生成方法都集中在一個抽象類中
- 產品的產出由生產的“工廠”決定
優缺點
- 通過抽象介面,通過改變內在實現,但不影響外部使用;
- 工廠可以決定元件的組裝方式,來產出不同的產品;
- 和抽象工廠(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