組合模式(Composite)的定義為:組合多個對象形成樹形結構,以表示整體-部分的結構層次。組合模式對單個對象和組合對象的使用具有一致性。其結構圖如下:

例如一個新聞的樹形菜單,它包含很多原始菜單(如國內、國際),以及由其子菜單組成的組合節點(如國內新聞下的時事、社會等),結構圖如下:

實現代碼:
//Menu.h
#include <string>
class Menu
{
public:
virtual ~Menu();
virtual void Add(Menu*);
virtual void Remove(Menu*);
virtual Menu* GetChild(int);
virtual void Display() = 0;
protected:
Menu();
Menu(std::string);
std::string m_strName;
};
//Menu.cpp
#include "stdafx.h"
#include "Menu.h"
Menu::Menu()
{
}
Menu::Menu(std::string strName) : m_strName(strName)
{
}
Menu::~Menu()
{
}
void Menu::Add(Menu* pMenu)
{}
void Menu::Remove(Menu* pMenu)
{}
Menu* Menu::GetChild(int index)
{
return NULL;
}
//SubMenu.h
#include "Menu.h"
class SubMenu : public Menu
{
public:
SubMenu();
SubMenu(std::string);
virtual ~SubMenu();
void Display();
};
//SubMenu.cpp
#include "stdafx.h"
#include "SubMenu.h"
#include <iostream>
using namespace std;
SubMenu::SubMenu()
{
}
SubMenu::SubMenu(string strName) : Menu(strName)
{
}
SubMenu::~SubMenu()
{
}
void SubMenu::Display()
{
cout << m_strName << endl;
}
//CompositMenu.h
#include "Menu.h"
#include <vector>
class CompositMenu : public Menu
{
public:
CompositMenu();
CompositMenu(std::string);
virtual ~CompositMenu();
void Add(Menu*);
void Remove(Menu*);
Menu* GetChild(int);
void Display();
private:
std::vector<Menu*> m_vMenu;
};
//CompositMenu.cpp
#include "stdafx.h"
#include "CompositMenu.h"
#include <iostream>
using namespace std;
CompositMenu::CompositMenu()
{
}
CompositMenu::CompositMenu(string strName) : Menu(strName)
{
}
CompositMenu::~CompositMenu()
{
}
void CompositMenu::Add(Menu* pMenu)
{
m_vMenu.push_back(pMenu);
}
void CompositMenu::Remove(Menu* pMenu)
{
m_vMenu.erase(&pMenu);
}
Menu* CompositMenu::GetChild(int index)
{
return m_vMenu[index];
}
void CompositMenu::Display()
{
cout << "+" << m_strName << endl;
vector<Menu*>::iterator it = m_vMenu.begin();
for (; it != m_vMenu.end(); ++it)
{
cout << "|-";
(*it)->Display();
}
}
#include "stdafx.h"
#include "Menu.h"
#include "SubMenu.h"
#include "CompositMenu.h"
int main(int argc, char* argv[])
{
Menu* pMenu = new CompositMenu("國內新聞");
pMenu->Add(new SubMenu("時事新聞"));
pMenu->Add(new SubMenu("社會新聞"));
pMenu->Display();
pMenu = new CompositMenu("國際新聞");
pMenu->Add(new SubMenu("國際要聞"));
pMenu->Add(new SubMenu("環球視野"));
pMenu->Display();
return 0;
}
最后輸出為:
+國內新聞
|-時事新聞
|-社會新聞
+國際新聞
|-國際要聞
|-環球視野