模式定义:
组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
这个模式能够创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。通过菜单和项放在相同结构中,我们创建了一个“整体/部分”层次结构,即由菜单和菜单项组成的对象树。使用组合结构,我们能把相同的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
模式结构:
Component:
为组合中的对象声明接口;<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1NrKyrWxx+m/9s/CyrXP1sv509DA4Lmy09C907/atcTIscqh0NDOqqO7PC9wPgo8cD7J+cP30ru49r3Tv9rTw9Pat8POyrncwO1Db21wb25lbnS1xNfT1+m8/jwvcD4KPHA+1Nq13bnpveG5udbQtqjS5dK7uPa907/ao6zTw9Pat8POytK7uPa4uLK/vP6jrLKi1Nq6z8rKtcTH6b/2z8LKtc/Wy/w8L3A+CjxwPjxzdHJvbmc+TGVhZjo8L3N0cm9uZz48L3A+CjxwPtTa1+m6z9bQse3KvtK2vdq147bUz/OjrNK2vdq148O709DX073ateOjrLKitqjS5cbk0NDOqjwvcD4KPHA+PHN0cm9uZz5Db21wb3NpdGU6PC9zdHJvbmc+PC9wPgo8cD62qNLl09DX07K/vP61xMTH0Kmyv7z+tcTQ0M6qPC9wPgo8cD605rSi19Oyv7z+PC9wPgo8cD7Ktc/W0+vX07K/vP7T0LnYtcSy2df3PC9wPgo8cD48c3Ryb25nPkNsaWVudDo8L3N0cm9uZz48L3A+CjxwPs2ouf1Db21wb25lbnS907/astnX99fpus+8/rrNuPax8LbUz/OhozwvcD4KPHA+IDwvcD4KPGgxPr7ZwP2jujwvaDE+CjxwPiAgICAgICAg1Nq1/LT6xvfA/dfT1tCjrM7Sw8fPo8371NrO57LNss21pdbQ1Pa809K7t921+LXjss21paOs0rK+zcrHy7XPo837xNzIw8zwteOyzbWlseSzyc7nss2yzbWltcTSu7j21KrL2KGjPC9wPgo8cD4gICAgICAgIM7Sw8e/ydLU08PX6brPxKPKvb3ivvbV4rj2zsrM4qO60ru/qsq8ztLDx7S0vajSu7j21+m8/r3Tv9rX986qss21pbrNssu1pc/utcS5ss2svdO/2qOsyMPO0sPHxNy5u9PDzbPSu7XE1/a3qMC0tKbA7bLLtaW6zbLLtaXP7qGju7u+5Luwy7WjrM7Sw8e/ydLU1eu21LLLtaW78rLLtaXP7rX308PP4M2stcS3vbeooaPIu7rzyrXP1rLLtaXP7rrN1+m6z7LLtaXX6bz+o6zS1Lywy/vDx7j319S1xLe9t6ihozwvcD4KPGgxPlVNTMnovMajujwvaDE+CjxwPjxpbWcgc3JjPQ=="https://www.cppentry.com/upload_files/article/49/1_2n6b0__.jpg" alt="\">
编程实现及执行结果:
#include
#include
#include
#include
using namespace std; //菜单和菜单项共同的
组件 class MenuComponent { public: virtual void add(MenuComponent* menuComponent) { throw exception("add error!"); } virtual void remove(MenuComponent* menuComponent) { throw exception("remove error!"); } virtual MenuComponent* getChild(int i) { throw exception("getChild error"); } virtual string getName() { throw exception("getName error"); } virtual string getDescription() { throw exception("getDescription error"); } virtual double getPrice() { throw exception("getPrice error"); } virtual void print() { throw exception("print error"); } }; //菜单项类 class MenuItem : public MenuComponent { public: MenuItem(){} MenuItem(string na, string descrip, double pric) { name = na; description = descrip; price = pric; } string getName() { return name; } string getDescription() { return description; } double getPrice() { return price; } void print() { cout << " " << getName() << ", " << getPrice() <<" ---" << getDescription() << endl; } private: string name; string description; double price; }; //组合菜单类 class Menu : public MenuComponent { public: Menu(string nam, string descri) { name = nam; description = descri; } void add(MenuComponent* pMenuComponent) { pMenuComponents.push_back(pMenuComponent); } void remove(MenuComponent* pMenuComponent) { vector
::iterator iter = pMenuComponents.begin(); for(; iter!=pMenuComponents.end(); ++iter) { if(*iter == pMenuComponent) { pMenuComponents.erase(iter); } } } MenuComponent* getChild(int i) { return pMenuComponents[i]; } string getName() { return name; } string getDescription() { return description; } void print() { cout << endl << getName() << ", " << getDescription() << endl << "--------------" << endl; vector
::iterator iter = pMenuComponents.begin(); while(iter != pMenuComponents.end()) { MenuComponent* pMenuComponent = *iter; pMenuComponent->print(); ++iter; } } private: vector
pMenuComponents; string name; string description; }; //服务生类 class Waitress { public: Waitress(MenuComponent* all_Menus) { allMenus = all_Menus; } void printMenu() { allMenus->print(); } private: MenuComponent* allMenus; }; //客户代码 int main() { MenuComponent* pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast"); MenuComponent* dinerMenu = new Menu("Diner MENU", "Lunch"); MenuComponent* dessertMenu = new Menu("DESSERT MENU","Dessert of coure!"); MenuComponent* allMenus = new Menu("ALL Menus", "All menus combined"); allMenus->add(pancakeHouseMenu); allMenus->add(dinerMenu); dinerMenu->add(new MenuItem("Pasta","Spaheti with Sauce", 3.89)); dinerMenu->add(dessertMenu); dessertMenu->add(new MenuItem("Apple Pie", "App pie with a cruse", 1.59)); Waitress* waitress = new Waitress(allMenus); waitress->printMenu(); return 0; }
执行结果:
ALLMenus, All menus combined
--------------
PANCAKEHOUSE MENU, Breakfast
--------------
DinerMENU, Lunch
--------------
Pasta, 3.89 ---Spaheti with Sauce
DESSERTMENU, Dessert of coure!
--------------
Apple Pie, 1.59 ---App pie with a cruse
请按任意键继续. . .