组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
代码背景为:餐厅里面的菜单,菜单里有菜单构成了树形结构。
#include <iostream> #include <string> #include <list> using namespace std; class MenuComponent { public: virtual void add(MenuComponent* menuComponent) { } virtual void remove(MenuComponent* menuComponent) { } virtual MenuComponent* getChild(int i) { MenuComponent* menuComponent; return menuComponent; } virtual string getName() { return "hi";} virtual string getDescription() {return "hi";} virtual double getPrice() {return 0.0; } virtual bool isVegetarian() {return true; } virtual void print() { } }; class Menu : public MenuComponent { public: list<MenuComponent*>* menuComponents; string name; string description; Menu(string name, string description) { menuComponents = new list<MenuComponent*>(); this->name = name; this->description = description; } virtual void add(MenuComponent* menuComponent) { menuComponents->push_back(menuComponent); } virtual void remove(MenuComponent* menuComponent) { menuComponents->remove(menuComponent); } virtual MenuComponent* getChild(int i) { list<MenuComponent*>::iterator iter = menuComponents->begin(); while(i-- && iter != menuComponents->end()) iter++; if(iter != menuComponents->end()) return (MenuComponent*)(*iter); } virtual string getName() { return name; } virtual string getDescription() { return description; } virtual void print() { cout<<endl<<getName()<<", " << getDescription()<<endl << "-------------"<<endl; list<MenuComponent*>::iterator iter = menuComponents->begin(); while(iter != menuComponents->end()) { (*iter)->print(); ++iter; } } }; class MenuItem : public MenuComponent { public: string name; string description; bool vegetarian; double price; MenuItem(){ } MenuItem(string name, string description, bool vegetarian, double price) { this->name = name; this->description = description; this->vegetarian = vegetarian; this->price = price; } virtual string getName() { return name; } virtual string getDescription() { return description; } virtual double getPrice() { return price; } virtual bool isVegetarian() { return vegetarian; } virtual void print() { cout<<" "<<getName(); if(isVegetarian()) cout<<"(v)"; cout <<", " <<getPrice()<<endl; cout <<" ---" << getDescription()<<endl; } }; class Waitress { public: MenuComponent* allMennus; Waitress(MenuComponent* allMennus) { this->allMennus = allMennus; } void printMenu() { allMennus->print(); } }; int main() { MenuComponent* pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast"); MenuComponent* dinerMenu = new Menu("DINER MENU", "Lunch"); MenuComponent* cafeMenu = new Menu("CAFE MENU", "Dinner"); MenuComponent* dessertMenu = new Menu("DESSERT MENU", "Dessert of course!"); MenuComponent* coffeeMenu = new Menu("COFFEE MENU", "Stuff to go with your afternoon coffee"); MenuComponent* allMenus = new Menu("ALL MENUS", "All menus combined"); allMenus->add(pancakeHouseMenu); allMenus->add(dinerMenu); allMenus->add(cafeMenu); pancakeHouseMenu->add(new MenuItem( "K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99)); pancakeHouseMenu->add(new MenuItem( "Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99)); pancakeHouseMenu->add(new MenuItem( "Blueberry Pancakes", "Pancakes made with fresh blueberries, and blueberry syrup", true, 3.49)); pancakeHouseMenu->add(new MenuItem( "Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59)); dinerMenu->add(new MenuItem( "Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99)); dinerMenu->add(new MenuItem( "BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99)); dinerMenu->add(new MenuItem( "Soup of the day", "A bowl of the soup of the day, with a side of potato salad", false, 3.29)); dinerMenu->add(new MenuItem( "Hotdog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05)); dinerMenu->add(new MenuItem( "Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99)); dinerMenu->add(new MenuItem( "Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89)); dinerMenu->add(dessertMenu); dessertMenu->add(new MenuItem( "Apple Pie", "Apple pie with a flakey crust, topped with vanilla icecream", true, 1.59)); dessertMenu->add(new MenuItem( "Cheesecake", "Creamy New York cheesecake, with a chocolate graham crust", true, 1.99)); dessertMenu->add(new MenuItem( "Sorbet", "A scoop of raspberry and a scoop of lime", true, 1.89)); cafeMenu->add(new MenuItem( "Veggie Burger and Air Fries", "Veggie burger on a whole wheat bun, lettuce, tomato, and fries", true, 3.99)); cafeMenu->add(new MenuItem( "Soup of the day", "A cup of the soup of the day, with a side salad", false, 3.69)); cafeMenu->add(new MenuItem( "Burrito", "A large burrito, with whole pinto beans, salsa, guacamole", true, 4.29)); cafeMenu->add(coffeeMenu); coffeeMenu->add(new MenuItem( "Coffee Cake", "Crumbly cake topped with cinnamon and walnuts", true, 1.59)); coffeeMenu->add(new MenuItem( "Bagel", "Flavors include sesame, poppyseed, cinnamon raisin, pumpkin", false, 0.69)); coffeeMenu->add(new MenuItem( "Biscotti", "Three almond or hazelnut biscotti cookies", true, 0.89)); Waitress* waitress = new Waitress(allMenus); waitress->printMenu(); return 0; }