[设计模式学习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 }
代码和部分定义参考:http://blog.csdn.net/lcl_data/article/details/8811101