橋接模式
將類的抽象部分與實(shí)現(xiàn)相分離
抽象部分與實(shí)現(xiàn)想分離吹榴,在成員函數(shù)方面用的是繼承,多態(tài)滚婉。
而在橋接模式是針對(duì)類的數(shù)據(jù)成員图筹。
如何將類的數(shù)據(jù)成員的抽象和實(shí)現(xiàn)想分離?
用的還是繼承:子類指針可以轉(zhuǎn)化為父類指針让腹。
想象一個(gè)場(chǎng)景:
電腦和操作系統(tǒng)远剩,電腦有很多戴爾、聯(lián)想骇窍、三星瓜晤。但是操作系統(tǒng)也有不少,win腹纳、linux痢掠、unix驱犹。
如果我們要描述一臺(tái)電腦,那么如果采用組合的方式足画,那么將至少有9個(gè)類來(lái)表示這些組合雄驹。
而橋接模式就是為了解決這個(gè)問(wèn)題的。
電腦可以擁有操作系統(tǒng)锌云,所以電腦這個(gè)類擁有一個(gè)win荠医、linux、unix的基類指針桑涎,那么電腦就可以擁有這三種不同的操作系統(tǒng)了。這個(gè)積累的指針就是這個(gè)“橋”兼贡,連鏈接一個(gè)要組合在一起的兩個(gè)對(duì)象攻冷。
//操作系統(tǒng)的基類
class OS
{
public:
virtual int version()=0;
};
//具體的操作系統(tǒng),另外還有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;
};
//或者也可以在構(gòu)造函數(shù)里傳入嘛等曼。
這就是橋接模式,說(shuō)白了就是一個(gè)可變類型的數(shù)據(jù)成員凿蒜,但是擁有相同的特征禁谦。
但是其實(shí),也是可以使用枚舉類型废封。也是可以實(shí)現(xiàn)這個(gè)橋
的功能州泊。
組合模式
模糊葉和枝干(枝干上可以在包含葉),為葉和枝干提供統(tǒng)一的管理方式
這個(gè)模式應(yīng)用的比較窄啊漂洋。
比如文件夾系統(tǒng)遥皂,還有菜單系統(tǒng),還有現(xiàn)實(shí)的樹(shù)干和葉刽漂。
為葉和枝干提供統(tǒng)一的管理模式演训,讓我們?cè)谠L問(wèn)的時(shí)候忽略其具體的類型。使用其統(tǒng)一的接口來(lái)訪問(wèn)贝咙。
上面這句話就清楚了透露出样悟,這兩個(gè)類型應(yīng)該可以放在同一個(gè)容器里,這兩個(gè)類型有相同的訪問(wèn)方式庭猩。所以這兩個(gè)類型應(yīng)該繼承自同一個(gè)類窟她。
但是葉和枝干的表現(xiàn)形式不同,所以其接口的行為也是不同的眯娱。比如葉不能再添加子節(jié)點(diǎn)(也就是再添加葉了)礁苗。所以這里有有兩種模式
- 透明方式:基類中提供統(tǒng)一的接口,這樣實(shí)現(xiàn)了徙缴,忽略具體類型试伙。但是如果為也葉節(jié)點(diǎn)添加元素嘁信,只能在運(yùn)行的時(shí)候報(bào)錯(cuò)。
- 安全方式:基類中不提供全部的接口疏叨,需要根據(jù)具體類型選擇接口潘靖,這樣在編譯的時(shí)候就能發(fā)現(xiàn)錯(cuò)誤。
既然組合模式蚤蔓,我覺(jué)得就應(yīng)該使用透明的方式卦溢,然后在實(shí)現(xiàn)的時(shí)候,子類不應(yīng)該含有的方法直接提示錯(cuò)誤秀又。也可以達(dá)到安全的方式单寂。
最后另一個(gè)問(wèn)題,一個(gè)枝干上可以有多個(gè)葉吐辙,而且以后還會(huì)添加宣决,所以其存儲(chǔ)元素的應(yīng)該是一個(gè)容器,存儲(chǔ)其基類指針的容器昏苏,而且尊沸,應(yīng)該是一個(gè)weak_ptr
,不過(guò)這個(gè)就忽略了。
//提供統(tǒng)一的方式
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;
};