模式定义:组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。
组合能让客户以一致的方式处理个别对象以及对象组合。
这个模式能够创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。
通过菜单和项放在相同结构中,我们创建了一个“整体/部分”层次结构,即由菜单和菜单项组成的对象树。
使用组合结构,我们能把相同的操作应用在组合和个别对象上。
换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
模式结构:Component:为组合中的对象声明接口;在适当情况下实现所有类共有接口的缺省行为;声明一个接口用于访问管理Component的子组件在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它Leaf:在组合中表示叶节点对象,叶节点没有子节点,并定义其行为Composite:定义有子部件的那些部件的行为存储子部件实现与子部件有关的操作Client:通过Component接口操作组合件和个别对象。
举例:在迭代器例子中,我们希望在午餐餐单中增加一份甜点餐单,也就是说希望能让甜点餐单变成午餐餐单的一个元素。
我们可以用组合模式解决这个问题:一开始我们创建一个组件接口作为餐单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。
换句话说,我们可以针对菜单或菜单项调用相同的方法。
然后实现菜单项和组合菜单组件,以及他们各自的方法。
UML设计:编程实现及执行结果:1.#include <iostream>2.#include <vector>3.#include <list>4.#include <string>5.ing namespace std;7.8.//菜单和菜单项共同的组件9.class MenuComponent10.{11.public:12.virtual void add(MenuComponent* menuComponent)13. {14.throw exception("add error!");15. }16.17.virtual void remove(MenuComponent* menuComponent)18. {19.throw exception("remove error!");20. }21.22.virtual MenuComponent* getChild(int i)23. {24.throw exception("getChild error");25. }26.27.virtual string getName()28. {29.throw exception("getName error");30. }31.32.virtual string getDescription()33. {34.throw exception("getDescription error");35. }36.37.virtual double getPrice()38. {39.throw exception("getPrice error");40. }41.42.virtual void print()43. {44.throw exception("print error");45. }46.};47.48.//菜单项类49.class MenuItem : public MenuComponent50.{51.public:52. MenuItem(){}53. MenuItem(string na, string descrip, double pric)55. name = na;56. description = descrip;57. price = pric;58. }59.60. string getName()61. {62.return name;63. }64.65. string getDescription()66. {67.return description;68. }69.70.double getPrice()71. {72.return price;73. }74.75.void print()76. {77. cout << " " << getName() << ", " << getPrice()78. <<" ---" << getDescription() << endl;79. }80.private:81. string name;82. string description;83.double price;84.};85.//组合菜单类86.class Menu : public MenuComponent87.{88.public:89. Menu(string nam, string descri)90. {91. name = nam;92. description = descri;93. }94.95.void add(MenuComponent* pMenuComponent)96. {97. pMenuComponents.push_back(pMenuComponent);99.100.void remove(MenuComponent* pMenuComponent)101. {102. vector<MenuComponent*>::iterator iter = pMenuComponents.begin(); 103.for(; iter!=pMenuComponents.end(); ++iter)104. {105.if(*iter == pMenuComponent)106. {107. pMenuComponents.erase(iter);108. }109. }110. }111.112. MenuComponent* getChild(int i)113. {114.return pMenuComponents[i];115. }116.117. string getName()118. {119.return name;120. }121.122. string getDescription()123. {124.return description;125. }126.127.void print()128. {129. cout << endl << getName() << ", " << getDescription() << endl << "--------------" << endl;130. vector<MenuComponent*>::iterator iter = pMenuComponents.begin(); 131.while(iter != pMenuComponents.end())132. {133. MenuComponent* pMenuComponent = *iter;134. pMenuComponent->print();135. ++iter;136. }137. }138.private:139. vector<MenuComponent*> pMenuComponents;140. string name;141. string description;142.};143.144.//服务生类145.class Waitress146.{147.public:148. Waitress(MenuComponent* all_Menus)149. {150. allMenus = all_Menus;151. }152.153.void printMenu()154. {155. allMenus->print();156. }157.private:158. MenuComponent* allMenus;159.};160.//客户代码161.int main()162.{163. MenuComponent* pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Break fast");164. MenuComponent* dinerMenu = new Menu("Diner MENU", "Lunch");165. MenuComponent* dessertMenu = new Menu("DESSERT MENU","Dessert of coure!");166.167. MenuComponent* allMenus = new Menu("ALL Menus", "All menus combined");168.169. allMenus->add(pancakeHouseMenu);170. allMenus->add(dinerMenu);171. dinerMenu->add(new MenuItem("Pasta","Spaheti with Sauce", 3.89)); 172.173. dinerMenu->add(dessertMenu);174. dessertMenu->add(new MenuItem("Apple Pie", "App pie with a cruse", 1.59 ));175.176. Waitress* waitress = new Waitress(allMenus);177. waitress->printMenu();178.return 0;179.}执行结果:ALLMenus, All menus combined--------------PANCAKEHOUSE MENU, Breakfast--------------DinerMENU, Lunch--------------Pasta, 3.89 ---Spaheti with SauceDESSERTMENU, Dessert of coure!--------------Apple Pie, 1.59 ---App pie with a cruse 请按任意键继续. . .。