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