[设计模式学习C++实现]---composite模式

composite模式(组合模式):

一.该设计模式主要用来解决如下问题:

如上图所示:我们有一个树形结构,也可以想象成文件管理系统。我们在处理每个节点的时候,不需要考虑它到底是什么节点,因为所实现的方法都是一样的。对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

二.组合模式又分为两种:

①透明模式:即在最高层component里面声明所有管理子类的方法(如:add,remove等),这样做的好处就是,对所有的对象接口统一了,可以同等的对待所有的对象,所以为透明模式。但是有些叶子节点是没有这些方法的,因此透明模式不安全。

②安全模式:在Composite类中声明管理子类的方法,这样做比较安全,但是不够透明,因为树叶类和合成类将具有不同的接口。

 

三.这种形式涉及到三个角色:

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。在安全式的合成模式里,构件角色并不是定义出管理子对象的方法,这一定义由树枝构件对象给出。

树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝对象给出所有的管理子对象的方法,如add()、remove()、getChild()等。

树叶构件(Leaf)角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。

  1 //Menu.h  
  2 #include <string>  
  3   
  4 class Menu    
  5 {  
  6 public:  
  7     virtual ~Menu();  
  8   
  9     virtual void Add(Menu*);  
 10     virtual void Remove(Menu*);  
 11     virtual Menu* GetChild(int);  
 12     virtual void Display() = 0;  
 13 protected:  
 14     Menu();  
 15     Menu(std::string);  
 16     std::string m_strName;  
 17 };  
 18   
 19 //Menu.cpp  
 20 #include "stdafx.h"  
 21 #include "Menu.h"  
 22   
 23 Menu::Menu()  
 24 {  
 25   
 26 }  
 27   
 28 Menu::Menu(std::string strName) : m_strName(strName)  
 29 {  
 30   
 31 }  
 32   
 33 Menu::~Menu()  
 34 {  
 35   
 36 }  
 37   
 38 void Menu::Add(Menu* pMenu)  
 39 {}  
 40   
 41 void Menu::Remove(Menu* pMenu)  
 42 {}  
 43   
 44 Menu* Menu::GetChild(int index)  
 45 {  
 46     return NULL;  
 47 }  
 48   
 49 //SubMenu.h  
 50 #include "Menu.h"  
 51   
 52 class SubMenu : public Menu    
 53 {  
 54 public:  
 55     SubMenu();  
 56     SubMenu(std::string);  
 57     virtual ~SubMenu();  
 58   
 59     void Display();  
 60 };  
 61   
 62 //SubMenu.cpp  
 63 #include "stdafx.h"  
 64 #include "SubMenu.h"  
 65 #include <iostream>  
 66   
 67 using namespace std;  
 68   
 69 SubMenu::SubMenu()  
 70 {  
 71   
 72 }  
 73   
 74 SubMenu::SubMenu(string strName) : Menu(strName)  
 75 {  
 76   
 77 }  
 78   
 79 SubMenu::~SubMenu()  
 80 {  
 81   
 82 }  
 83   
 84 void SubMenu::Display()  
 85 {  
 86     cout << m_strName << endl;  
 87 }  
 88   
 89 //CompositMenu.h  
 90 #include "Menu.h"  
 91 #include <vector>  
 92   
 93 class CompositMenu : public Menu  
 94 {  
 95 public:  
 96     CompositMenu();  
 97     CompositMenu(std::string);  
 98     virtual ~CompositMenu();  
 99   
100     void Add(Menu*);  
101     void Remove(Menu*);  
102     Menu* GetChild(int);  
103     void Display();  
104 private:  
105     std::vector<Menu*> m_vMenu;  
106 };  
107   
108 //CompositMenu.cpp  
109 #include "stdafx.h"  
110 #include "CompositMenu.h"  
111 #include <iostream>  
112   
113 using namespace std;  
114   
115 CompositMenu::CompositMenu()  
116 {  
117       
118 }  
119   
120 CompositMenu::CompositMenu(string strName) : Menu(strName)  
121 {  
122   
123 }  
124   
125 CompositMenu::~CompositMenu()  
126 {  
127   
128 }  
129   
130 void CompositMenu::Add(Menu* pMenu)  
131 {  
132     m_vMenu.push_back(pMenu);  
133 }  
134   
135 void CompositMenu::Remove(Menu* pMenu)  
136 {  
137     m_vMenu.erase(&pMenu);  
138 }  
139   
140 Menu* CompositMenu::GetChild(int index)  
141 {  
142     return m_vMenu[index];  
143 }  
144   
145 void CompositMenu::Display()  
146 {  
147     cout << "+" << m_strName << endl;  
148     vector<Menu*>::iterator it = m_vMenu.begin();  
149     for (; it != m_vMenu.end(); ++it)  
150     {  
151         cout << "|-";  
152         (*it)->Display();  
153     }  
154 }  
155   
156 #include "stdafx.h"  
157 #include "Menu.h"  
158 #include "SubMenu.h"  
159 #include "CompositMenu.h"  
160   
161 int main(int argc, char* argv[])  
162 {  
163     Menu* pMenu = new CompositMenu("国内新闻");  
164     pMenu->Add(new SubMenu("时事新闻"));  
165     pMenu->Add(new SubMenu("社会新闻"));  
166     pMenu->Display();  
167     pMenu = new CompositMenu("国际新闻");  
168     pMenu->Add(new SubMenu("国际要闻"));  
169     pMenu->Add(new SubMenu("环球视野"));  
170     pMenu->Display();  
171   
172     return 0;  
173 }  
Composit

 

代码和部分定义参考:http://blog.csdn.net/lcl_data/article/details/8811101

 

 

 

 

posted @ 2013-05-26 22:05  mengmee  阅读(198)  评论(0编辑  收藏  举报