組合模式(Composite):將對象組合成樹形結構以表示‘部分-整體’的階層。組合模式使得使用者物件單個對象和組合對象的使用具有一致性。
組合模式結構圖:
理解:
1. Component是組合對象的基類,定義了類的公用方法;提供一個訪問和管理子組件的方法。
管理子組件的方法:Add-添加子組件;Remove-移除子組件;
2. Leaf是組合對象的葉子節點(樹葉)。葉子節點沒有子組件(也就沒有管理子組件的方法)。
3. Composite是具體的子組件類(樹枝)。實現基類介面。它可以繼續派生子組件或者葉子節點。
4. Client通過Component基類來操作組合對象。
Component為組合中的對象聲明介面(基類),在適當情況下,實現所有類共有介面的預設行為。聲明一個介面用於訪問和管理Component的子組件。
class Component
{
protected:
String name;
public:
virtual void Add(Component *c)=0; //通常都用add和remove方法來提供增加或移//除樹葉或樹枝的功能
virtual void Remove(Component *c)=0;
virtual void Display(int depth);
};
Leaf在組合中表示分葉節點對象,分葉節點沒有子節點。
class Leaf : public Component
{
public:
Leaf(String name):Component(name){}
void Add(Component * c)
{
cout<< “Cannot add to a leaf”<<endl;
}
void Remove(Component *c)
{
cout<< “Cannot remove from a leaf”<<endl;
}
void Display(int depth)
{
for(int i=0; i<depth;i++)
cout<< “—”;
cout<<name<<endl;
}
};
//由於葉子沒有再增加分支和樹葉,所以add和remove方法實現它沒有意義,但這樣做可以消除分葉節點和枝節點對象在抽象層次的區別,它們具備完全一致的介面。
Composite定義有枝節點行為,用來儲存子組件,在Component介面中實現與子組件有關操作,比如增加Add和刪除Remove
class Composite :public Component
{
private:
list<Component *> children = newlist<Component *>();
public:
Composite(String name):Component(name){}
void Add(Component* c)
{
children.push_back(c);
}
void Remove(Component * c)
{
children.remove(c);
}
void Display(int depth)
{
for(int i=0; i<depth;i++)
cout<< “—”;
cout<<name<<endl;
list<Component *>::iteratorit=children.begin();
for(;it!=children.end();it++)
{
*it->Display(depth+2);
}
}
};
用戶端代碼,能通過Component介面操作組合組件的對象
void main()
{
Composite *root = new Composite(“root”);
root->Add(new Leaf(“Leaf A”));
root->Add(new Leaf(“Leaf B”));
Composite *comp = new Composite(“CompositeX”);
comp->Add(new Leaf(“Leaf XA”));
comp->Add(new Leaf(“Leaf XB”));
root->Add(comp);
Composite *comp2 = new Composite(“CompositeXY”);
Comp2->Add(new Leaf(“Leaf XYA”));
Comp2->Add(new Leaf(“Leaf XYB”));
comp->Add(comp2);
root->Display(1);
}
結果顯示:
—root
———Leaf A
———Leaf B
———Composite X
—————Leaf XA
—————Leaf XA
—————Composite XY
———————Leaf XYA
———————Leaf XYA
何時使用組合模式:
需求中是體現部分與整體層次的結構時,以及希望使用者可以忽略組合對象與單個對象的不同,統一地使用組合結構中的所有對象時,就應該考慮用組合模式。