抽象工廠 abstract factory
例子
考慮一個多風格的界面應用,要求可以切換不同風格類型的組件(窗口,滾動條,按鈕等)
風格/組件 | pm風格 | motif風格 |
---|---|---|
滾動條 | pmScrollBar | motifScrollBar |
窗口 | pmWindow | MotifWindow |
WidgetFactory: 抽象工廠,用于創(chuàng)建滾動條和窗口。
MotifWidgetFactory: 繼承抽象工廠(WidgetFactory),用于給Motif類型創(chuàng)建滾動條和窗口。
他依賴于MotifWindow和MotifScrollBar
PMWidgetFactory: 繼承抽象工廠(WidgetFactory),用于給PM類型創(chuàng)建滾動條和窗口。
他依賴于PMWindow和PMScrollBar
Client: 客戶端,用來操作軟件或者系統(tǒng)
結構
builder 模式
例子
支持多種格式的富文本閱讀器(RTF),比如tex文本,ASCII, WIDGET
客戶端解析文本時,先選擇builder,然后根據(jù)文本流不同類型,轉換不同成不同的格式
比如:tex格式支持復雜的數(shù)學公式,只有texbuilder有這個分支
結構
- Builder (TextConverter) 建造者
specifies an abstract interface for creating parts of a Product object. (為了創(chuàng)建一個對象或者對象的部分而指定一個抽象接口) - ConcreteBuilder (ASCIIConverter, TeXConverter, TextWidgetConverter) 具體建造者
constructs and assembles parts of the product by implementing the Builder interface. (通過實現(xiàn)建造接口來構建一個產品或者產品的部分)
defines and keeps track of the representation it creates. (定義并跟蹤所創(chuàng)建的表現(xiàn)方式)
provides an interface for retrieving the product (e.g., GetASCIIText, GetTextWidget). (提供一個獲取產品的接口) - Director (RTFReader) 指揮者
constructs an object using the Builder interface. (用建造接口創(chuàng)建一個對象) - Product (ASCIIText, TeXText, TextWidget) 產品
represents the complex object under construction. (表示一個正在構建的復雜對象)ConcreteBuilder builds the product’s internal representation and defines the process by which it’s assembled. (具體的建造者構建產品的內部展示,并定義了產品的組裝過程)
includes classes that define the constituent parts (包含構成產品的部件), including interfaces for assembling the parts into the final result. (包含將部件組成最終結果的接口)
factory method 工廠方法
未完待續(xù)
對比
背景:設計一個迷宮,僅考慮迷宮的構成:由一系列房間,墻,門組成。房間知道鄰居是誰:房間,墻或者門。門連接兩個房間。忽略所有和游戲者相關的操作:移動,顯示等。
定義方向:enum Direction {North,South, East, West}
迷宮組件公共抽象類 MapSite
不使用設計模式
Class MapSite
{
public:
virtual void Enter()=0;
};
class Room : public MapSite {
public :
Room (int roomNo)
MapSite* GetSide (Direction) const;
void SetSide (Direction, Mapsite*);
virtual void Enter()
private:
MapSite* _sides[4] ;
int _roomNumber;
};
class Wall : public MapSite {
public :
Wall();
virtual void Enter( ) ;
};
class Door public Mapsite {
public :
Door (Room* = 0, Room* = 0) ;
virtual void Enter ( )
Room* OtherSideFrom (Room* ) ;
private :
Room* _room1;
Room* _room2;
bool _isOpen ;
} ;
class Maze
{
Public:
Maze ;
void AddRoom (Room* ) ;
Room* RoomNo ( int) const ;
private:
//…
};
//創(chuàng)建迷宮
Maze *MazeGame()
{
Maze* aMaze =new Maze;
Room *r1 = new Room(1);
Room *r2 = new Room(2);
Door theDoor = new Door(r1,r2);
aMaze ->AddRoom(r1);
aMaze ->AddRoom(r2);
r1->SetSide(North, new Wall);
r1->SetSide(South, theDoor );
r1->SetSide(East, new Wall);
r1->SetSide(West, new Wall);
r2 ->SetSide(North, new Wall);
r2 ->SetSide(South, new Wall);
r2 ->SetSide(East, new Wall);
r2 ->SetSide(West, theDoor );
return aMaze;
}
抽象工廠
class MazeFactory (
public
MazeFactory ( ) ;
virtual Maze* MakeMaze() const
{return new Maze; }
virtual Wall* MakeWall() const
{return new Wall; }
virtual Room* MakeRoom(int n) const
{return new Room(n)} )
virtual Door* MakeDoor ( Room* r1, Room* r2) const
{return new Door (rl, r2); }
}
class BombedMazeFactory : public MazeFactory(
public
BombedMazeFactory ( ) ;
virtual Maze* MakeMaze() const
{return new Maze; }
virtual Wall* MakeWall() const
{return new BombedWall; }
virtual Room* MakeRoom(int n) const
{return new BombedRoom(n)} )
virtual Door* MakeDoor ( Room* r1, Room* r2) const
{return new BombedDoor (rl, r2); }
}
Maze *MazeGame:: CreateMaze(MazeFactory & factory)
{
Maze* aMaze =factory. MakeMaze() ;
Room *r1 = factory. MakeRoom(1) ;
Room *r2 =factory. MakeRoom(2) ;
Door theDoor = factory.MakeDoor(r1,r2);
aMaze ->AddRoom(r1);
aMaze ->AddRoom(r2);
r1->SetSide(North, factory.MakeWall() );
r1->SetSide(South, theDoor );
r1->SetSide(East, factory.MakeWall() );
r1->SetSide(West, factory.MakeWall() );
r2 ->SetSide(North, factory.MakeWall() );
r2 ->SetSide(South, factory.MakeWall() );
r2 ->SetSide(East, factory.MakeWall() );
r2 ->SetSide(West, theDoor );
return aMaze;
}
builder
Builder 模式
class MazeBuilder {
public:
virtual void BuildMaze (){}
virtual void BuildRoom (int room) { }
virtual void BuildDoor (int roomFrom. int roomTo ) { }
virtual Maze* GetMaze () { return 0 ; }
protected :
MazeBuiIder();
};
該 接 口 可 以 創(chuàng) 建 : 1 ) 迷 宮 。 2 ) 有 一 個 特 定 房 間 號 的 房 間 。 3 ) 在 有 號 碼 的 房 間 之 間 的 門 。
GetMaze 操 作 返 回 這 個 迷 宮 給 客 戶 。 MazeBu11der 的 子 類 將 重 定 義 這 些 操 作 , 返 回 它 們 所 創(chuàng) 建
的 迷 宮 。
不定義為純虛函數(shù),是為了方便派生類只重定義它們感興趣的接口
用 MazeBuilder 接 口 , 我 們 可 以 改 變 createMaze 成 員 函 數(shù) , 以 生 成 器 作 為 它 的 參 數(shù) 。
Maze* MazeGame ::CreateMaze (MazeBuilder & builder)
{
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1,2) ;
return builder.GetMaze();
}
將 這 個 createMaze 版 本 與 原 來 的 相 比 , 注 意 生 成 器 是 如 何 隱 藏 迷 宮 的 內 部 表 示 的 一 一 一 即 定
義 房 間 、 門 和 墻 壁 的 那 些 類 . 一 一 以 及 這 些 部 件 是 如 何 組 裝 成 最 終 的 迷 宮 的 。 有 人 可 能 猜 測 到
有 一 些 類 是 用 來 表 示 房 間 和 門 的 , 但 沒 有 跡 象 顯 示 哪 個 類 是 用 來 表 示 墻 壁 的 。 這 就 使 得 改 變
一 個 迷 宮 的 表 示 方 式 要 容 易 一 些 , 因 為 所 有 MazeBuiIder 的 客 戶 都 不 需 要 被 改 變 。
MazeBuilder自己并不創(chuàng)建迷宮,子 類 做 實 際 工 作:
子 類 StandardMazeBuilder :一 個 創(chuàng) 建 簡 單 迷 宮 的 實 現(xiàn) 。 它 將 它 正 在 創(chuàng) 建 的 迷 宮 放 在 變 量 _currentMaze 中 。
class StandardMazeBuiIder : public MazeBuilder
{
Public:
StandardMazeBuilder(){ _currentMaze=0};
virtual void BuildMaze (){ _currentMaze = new Maze;}
virtual void BuildRoom (int room) { }
virtual void BuildDoor (int roomFrom. int roomTo ) { }
virtual Maze* GetMaze () 〔 return _currentMaze; }
Private:
Direction CommonWall( room*, Room*);
Maze* _currentMaze;
}
//創(chuàng)造一個都是墻的房間
void StandardMazeBuilder :: BuildRoom (int n)
{
if (! _currentMaze—>RoomNo (n))
{
Room room =new Room(n);
_currentMaze->AddRoom(room);
room->SetSide (North, new Wall);
room->SetSide(South, new Wall);
room->SetSide(East, new Wall);
room->SetSide(West, nev Wall);
}
}
//建造一扇兩個房間之間的門,其中CommonWall找到兩個房間相鄰的墻壁
Void StandardMazeBuilder::BuildDoor(int n1, int n2)
{
Room* r1 = _currentMaze->RoomNo(n1);
Room* r2 = _currentMaze->RoomNo(n2);
Door *d = new Door(r1,r2);
r1->SetSide(CommonWall(r1,r2) , d);
r1->SetSide(CommonWall(r2,r1) , d);
}
現(xiàn)在客戶可以創(chuàng)建迷宮了
Maze* maze;
MazeGame game;
StandardMazeBuiIder builder ;
game. CreateMaze (builder)
Maze= builder.GetMaze();
我 們 本 可 以 將 所 有 的 standardMazeBuiIderN 作 放 在 Maze 中 并 讓 每 一 個 Maze 創(chuàng) 建 它 自 身 。
但 將 Maze 變 得 小 一 些 使 得 它 能 更 容 易 被 理 解 和 修 改 , 而 且 standardMazeBuiIder 易 于 從 Maze 中
分 離 。 更 重 要 的 是 , 將 兩 者 分 離 使 得 你 可 以 有 多 種 MazeB 回 der , 每 一 種 使 用 不 同 的 房 間 、 墻
壁 和 門 的 類 。文章來源:http://www.zghlxwxcb.cn/news/detail-601079.html
對比
抽象工廠模式強調的是創(chuàng)造不同系列的產品,所以每個產品都有一個抽象類,比如window。而builder模式中,可能無法抽取公共產品抽象類,它更強調產品的構建方式,所以void StandardMazeBuilder :: BuildRoom (int n) 中直接定義了房間是怎么構建的,而在抽象工廠模式這個過程不在MazeFactory 里面而在Maze *MazeGame:: CreateMaze(MazeFactory & factory)函數(shù)里,也就是說MazeFactory 只負責創(chuàng)建不同類型的產品,客戶負責組裝;Builder 則自己組裝想要的產品,客戶直接拿文章來源地址http://www.zghlxwxcb.cn/news/detail-601079.html
到了這里,關于設計模式:創(chuàng)建型模式的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!