组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
代码背景为:餐厅里面的菜单,菜单里有菜单构成了树形结构。
#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;
}