1.1 BUILDER生成器
1、 意圖
將一個復雜對象的構建和它的表示分離,使得同樣的構建過程可以創建不同的表示。
構建是通過對生成器抽象接口的調用實現的。而構建出來的產品的類型(表示),是由具體的進行構建的生成器的子類的實例來決定的。這樣導向器只需要調用生成器的抽象接口生成產品,而具體生成什么樣的產品,則是根據導向器配置的具體的生成器實例相關。
終于理解了它是如何把復雜對象的構建和它的表示分離的,也理解了為什么同樣的構建過程。
2、 動機
3、 適用性
當創建復雜對象的算法應該獨立于該對象的組成以及他們的裝配方式時——對象的組成及裝配方式是生成器的抽象接口來表示的。而對象的創建的算法是有生成器的子類實現的。
當構造過程必須允許被構造的對象有不同的表示時——也就是,同樣的構造過程,可以生成不同的產品。這里是通過配置導向器的生成器的子類實例來實現的。
4、 結構
5、 參與者
l Builder:為創建一個product對象的各個部件指定抽象接口。這些部件最終構成了product,而對這些抽象接口的調用,則是裝配product的操作,調用的次數,入參等不同,則最終生成的product也不同。product本身的構造過程可能會非常復雜。但是,這些復雜度對Director(導向者)是隱藏的。這些抽象的接口描述了產品的組成以及裝配方式。
l ConcreteBuilder:實現Builder的接口以構造和裝配產品的各個部件;定義并明確它所創建的表示;提供一個檢索產品的接口。這個類實現了Builder的抽象接口,從而可以創建不同的表示,但是組成和裝配過程還是一樣的。
l Director:構造一個使用Builder抽象接口的對象。更對象根據Builder的接口來裝配并生產產品。
l Product:表示被構造的復雜的對象。ConcreteBuilder創建該產品的內部表示,并定義它的裝配過程;包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。
6、 協作
l 客戶創建Director對象,并用它想要的Builder對象進行配置。
l 一旦產品不僅被生成,導向器就會通知生成器。
l 生成器處理導向器請求,并且將部件添加到該產品中。
l 客戶從生成器中檢索產品。
7、 效果
l 它使你可以改變一個產品的內部表示。Builder提供給Director的抽象接口可以使生成器隱藏這個產品的表示和內部結構。它同時也隱藏了該產品時如何裝配的。因為產品時通過抽象接口構造的,你改變該產品的內部表示時,所要做的只是定義一個新的生成器。
l 它將構造代碼和表示代碼分開。Builder模式通過封裝一個復雜對象的創建和表示方式提高了對象的模塊性。每個ConcreteBuilder包含了創建和裝配一個特定產品的所有代碼。
l 它可以使你對構造過程進行更精細的控制。
8、 實現
l 通常一個抽象的Builder類為導向者可能要求創建的每一個構件定義一個操作。這些操作缺省什么也不做。一個ConcreteBuilder類對它有興趣創建的構建重定義這些操作。
l 裝配和構造接口:一般構造請求的結果只是被添加到產品中,特殊情況下,需要返回給導向器。
l 產品沒有抽象類:一般他們沒有公共的部分。如果有也可以設置一個抽象類。
l Builder中缺省的方法為空。
9、 代碼示例
class MazeBuilder {
public:
virtual void BuildMaze() { }//部件的構造方法
virtual void BuildRoom(int room) { }
virtual void BuildDoor(int roomFrom, int roomTo) { }
virtual Maze* GetMaze() { return 0; }
protected:
MazeBuilder();
};//MazeBuilder是生成器
class StandardMazeBuilder : public MazeBuilder {
public:
StandardMazeBuilder();
/*
*/
virtual void BuildMaze();
virtual void BuildRoom(int);
virtual void BuildDoor(int, int);
/*
*/
virtual Maze* GetMaze();
private:
Direction CommonWall(Room*, Room*);
Maze* _currentMaze;
};//StandardMazeBuilder是ConcreteBuilder,提供部件的具體構造代碼
Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1, 2);
return builder.GetMaze();
}//CreateMaze是導向器,調用生成器的抽象接口完成產品的構造過程。
//下面代碼描述產品的構造過程
Maze* maze;//最終的產品
MazeGame game;//Director,導航者
StandardMazeBuilder builder;//ConcreteBuilder,實際的構造類
game.CreateMaze(builder);//開始裝配
maze = builder.GetMaze();//獲取裝配后的產品