組合模式為了描述分支包含關係,也就是我們說的樹形關係,其對象分為枝和葉,每一枝可包含枝和葉,直到全部為葉節點。我們對枝和葉進行行為抽象,可認為枝和葉都是Component,而葉是最小的操作單元,其下不存在枝和葉,而枝作為Composite裡面存有其下枝和葉的組件列表。 作用 將對象組合成樹形結構以表 ...
組合模式為了描述分支包含關係,也就是我們說的樹形關係,其對象分為枝和葉,每一枝可包含枝和葉,直到全部為葉節點。我們對枝和葉進行行為抽象,可認為枝和葉都是Component,而葉是最小的操作單元,其下不存在枝和葉,而枝作為Composite裡面存有其下枝和葉的組件列表。
作用
將對象組合成樹形結構以表示“部分-整體”的層次結構,使得用戶對單個對象和組合對象的使用具有一致性
類視圖
實現
#include <iostream>
#include <list>
#include <string>
using namespace std;
class menu
{
public:
menu(string in) : name(in){}
~menu(){}
virtual void Add(menu*) = 0;
virtual void Remove(menu*) = 0;
virtual void showname() = 0;
protected:
string name;
};
class Leafmenu : public menu
{
public:
Leafmenu(string in) : menu(in){}
~Leafmenu(){}
void showname()
{
cout<< "Leaf : " << name << endl;
}
virtual void Add(menu*){}
virtual void Remove(menu*){}
};
class Compositemenu : public menu
{
public:
Compositemenu(string in) : menu(in){}
void showname()
{
cout<< "Composit : "<< name << endl;
list<menu*>::iterator iter = m_child.begin();
while (iter != m_child.end())
{
(*iter)->showname();
iter++;
}
}
virtual void Add(menu*m){ m_child.push_back(m); }
virtual void Remove(menu*m){ m_child.remove(m); }
private:
list<menu*> m_child;
};
//調用實現
int main
{
Compositemenu mainmenu("Main");
/***添加File菜單****/
Compositemenu *pFile = new Compositemenu("File");
Leafmenu *pNew = new Leafmenu("New");
Leafmenu *pOpen = new Leafmenu("Open");
Leafmenu *pClose = new Leafmenu("Close");
pFile->Add(pNew);
pFile->Add(pOpen);
pFile->Add(pClose);
mainmenu.Add(pFile);
/***添加Edit菜單****/
Compositemenu *pEdit = new Compositemenu("Edit");
Leafmenu *pCopy = new Leafmenu("Copy");
Leafmenu *pPaste = new Leafmenu("Paste");
pEdit->Add(pCopy);
pEdit->Add(pPaste);
mainmenu.Add(pFile);
Leafmenu *pExit = new Leafmenu("Exit");
Leafmenu *pHelp = new Leafmenu("Help");
mainmenu.Add(pExit);
mainmenu.Add(pHelp);
mainmenu.showname();
delete pNew;
delete pOpen;
delete pClose;
delete pFile;
delete pCopy;
delete pPaste;
delete pEdit;
delete pExit;
delete pHelp;
}
關於葉對節點的操作方法,如上面例子中add、remove、get等,其實是不需要的,因為基類申明的是純虛函數,所以必須進行實現,但是在調用時沒有任何意義,這就帶來了一些使用的風險,安全的做法是將這些操作從基類中移除,添加到composite類中,這樣在編譯時就可以檢查到調用問題,不過這樣做顯然又阻礙了介面的一致性,權衡利弊的選擇還需自己根據需要來。
應用場景
常用的樹形結構操作,如文件結構、菜單、組織結構等