橋接模式
將類的抽象部分與實現相分離
抽象部分與實現想分離,在成員函數方面用的是繼承,多態。
而在橋接模式是針對類的數據成員。
如何將類的數據成員的抽象和實現想分離?
用的還是繼承:子類指針可以轉化為父類指針。
想象一個場景:
電腦和操作系統,電腦有很多戴爾、聯想、三星。但是操作系統也有不少,win、linux、unix。
如果我們要描述一臺電腦,那么如果采用組合的方式,那么將至少有9個類來表示這些組合。
而橋接模式就是為了解決這個問題的。
電腦可以擁有操作系統,所以電腦這個類擁有一個win、linux、unix的基類指針,那么電腦就可以擁有這三種不同的操作系統了。這個積累的指針就是這個“橋”,連鏈接一個要組合在一起的兩個對象。
//操作系統的基類
class OS
{
public:
virtual int version()=0;
};
//具體的操作系統,另外還有win、unix
class linux:public OS
{
public:
virtual int version();
};
//電腦的基類
class Computer
{
public:
vtual void installOs(OS *os)=0;
};
//具體的電腦類
class Dell"public Computer
{
public:
virtual void installOs(Os *os);
private:
OS* _os;
};
//或者也可以在構造函數里傳入嘛。
這就是橋接模式,說白了就是一個可變類型的數據成員,但是擁有相同的特征。
但是其實,也是可以使用枚舉類型。也是可以實現這個橋
的功能。
組合模式
模糊葉和枝干(枝干上可以在包含葉),為葉和枝干提供統一的管理方式
這個模式應用的比較窄啊。
比如文件夾系統,還有菜單系統,還有現實的樹干和葉。
為葉和枝干提供統一的管理模式,讓我們在訪問的時候忽略其具體的類型。使用其統一的接口來訪問。
上面這句話就清楚了透露出,這兩個類型應該可以放在同一個容器里,這兩個類型有相同的訪問方式。所以這兩個類型應該繼承自同一個類。
但是葉和枝干的表現形式不同,所以其接口的行為也是不同的。比如葉不能再添加子節點(也就是再添加葉了)。所以這里有有兩種模式
- 透明方式:基類中提供統一的接口,這樣實現了,忽略具體類型。但是如果為也葉節點添加元素,只能在運行的時候報錯。
- 安全方式:基類中不提供全部的接口,需要根據具體類型選擇接口,這樣在編譯的時候就能發現錯誤。
既然組合模式,我覺得就應該使用透明的方式,然后在實現的時候,子類不應該含有的方法直接提示錯誤。也可以達到安全的方式。
最后另一個問題,一個枝干上可以有多個葉,而且以后還會添加,所以其存儲元素的應該是一個容器,存儲其基類指針的容器,而且,應該是一個weak_ptr
,不過這個就忽略了。
//提供統一的方式
class Node
{
public:
virtual void add(Node*)=0;
virtual void remove(Node*)=0;
virtual Node* show(int index)=0;
};
class left:public Node
{
//。。。。
private:
vector<Node*> _list;
};
class Branch:public Node
{
//。。。
private:
vector<Node*> _list;
};