作用:
將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)芳绩。Composite使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
UML結(jié)構(gòu)圖:
抽象基類:
1)Component:為組合中的對(duì)象聲明接口,聲明了類共有接口的缺省行為(如這里的Add,Remove,GetChild函數(shù)),聲明一個(gè)接口函數(shù)可以訪問(wèn)Component的子組件.
接口函數(shù):
1)Component::Operatation:定義了各個(gè)組件共有的行為接口,由各個(gè)組件的具體實(shí)現(xiàn).
2)Component::Add添加一個(gè)子組件
3)Component::Remove::刪除一個(gè)子組件.
4)Component::GetChild:獲得子組件的指針.
解析:
Component模式是為解決組件之間的遞歸組合提供了解決的辦法,它主要分為兩個(gè)派生類,其中的Leaf是葉子結(jié)點(diǎn),也就是不含有子組件的結(jié)點(diǎn),而Composite是含有子組件的類.舉一個(gè)例子來(lái)說(shuō)明這個(gè)模式,在UI的設(shè)計(jì)中,最基本的控件是諸如Button,Edit這樣的控件,相當(dāng)于是這里的Leaf組件,而比較復(fù)雜的控件比如List則可也看做是由這些基本的組件組合起來(lái)的控件,相當(dāng)于這里的Composite,它們之間有一些行為含義是相同的,比如在控件上作一個(gè)點(diǎn)擊,移動(dòng)操作等等的,這些都可以定義為抽象基類中的接口虛函數(shù),由各個(gè)派生類去實(shí)現(xiàn)之,這些都會(huì)有的行為就是這里的Operation函數(shù),而添加,刪除等進(jìn)行組件組合的操作只有非葉子結(jié)點(diǎn)才可能有,所以虛擬基類中只是提供接口而且默認(rèn)的實(shí)現(xiàn)是什么都不做.
這里有個(gè)問(wèn)題。當(dāng)虛擬基類里實(shí)現(xiàn)接口時(shí)闻察。葉節(jié)點(diǎn)也會(huì)繼承捆探。但是你去執(zhí)行這個(gè)方法時(shí),卻沒有得到想要的結(jié)果斤吐。(因?yàn)槿~節(jié)點(diǎn)沒有子節(jié)點(diǎn))搔涝;所以,下面代碼將借口放在了樹節(jié)點(diǎn)里面和措。當(dāng)然庄呈,這樣的問(wèn)題就是,你需要判斷哪個(gè)是樹節(jié)點(diǎn)派阱,才能夠執(zhí)行這些方法诬留。
實(shí)現(xiàn):
#include#include#include#includeusing namespace std;class Component{public:? ? virtual void process() = 0;? ? virtual ~Component(){}};//樹節(jié)點(diǎn)class Composite : public Component{? ? ? ? string name;? ? listelements;
public:
Composite(const string & s) : name(s) {}
void add(Component* element) {
elements.push_back(element);
}
void remove(Component* element){
elements.remove(element);
}
void process(){
//1. process current node
//2. process leaf nodes
for (auto &e : elements)
e->process(); //多態(tài)調(diào)用
}
};
//葉子節(jié)點(diǎn)
class Leaf : public Component{
string name;
public:
Leaf(string s) : name(s) {}
void process(){
//process current node
}
};
void Invoke(Component & c){
//...
c.process();
//...
}
int main()
{
Composite root("root");
Composite treeNode1("treeNode1");
Composite treeNode2("treeNode2");
Composite treeNode3("treeNode3");
Composite treeNode4("treeNode4");
Leaf leat1("left1");
Leaf leat2("left2");
root.add(&treeNode1);
treeNode1.add(&treeNode2);
treeNode2.add(&leaf1);
root.add(&treeNode3);
treeNode3.add(&treeNode4);
treeNode4.add(&leaf2);
process(root);
process(leaf2);
process(treeNode3);
}