组合模式:允许你将对象组成树形结构来表现“整体/部分”的层次结构。组合能让客户以一致性的方式处理个别对象和对象组合。
类图如下:
更为形象的表示如下:
代码如下:
/*MenuComponent.h*/
#pragma once
#include "UnsupportedOperationException.h"
#include <string>
class MenuComponent
{
public:
MenuComponent(){}
virtual ~MenuComponent(){}
//此处做了抛出异常处理,下一篇文档完善这块代码
virtual void add(MenuComponent* menuComponent)
{
throw new UnsupportedOperationException();
}
virtual void remove(MenuComponent* menuComponent)
{
throw new UnsupportedOperationException();
}
virtual MenuComponent* getChild(int i)
{
throw new UnsupportedOperationException();
}
virtual std::string getName()
{
throw new UnsupportedOperationException();
}
virtual std::string getDescription()
{
throw new UnsupportedOperationException();
}
virtual float getPrice()
{
throw new UnsupportedOperationException();
}
virtual bool isVegetarian()
{
throw new UnsupportedOperationException();
}
virtual void print()
{
throw new UnsupportedOperationException();
}
};
/*Menu.h*/
#pragma once
#include "MenuComponent.h"
#include <vector>
#include <algorithm>
#include <iostream>
class Menu : public MenuComponent
{
private:
std::vector<MenuComponent*> menuComponents;
std::string name;
std::string description;
public:
Menu(std::string _name,std::string _description):
name(_name), description(_description){}
void add(MenuComponent* menuComponent)
{
menuComponents.push_back(menuComponent);
}
void remove(MenuComponent* menuComponent)
{
std::remove(menuComponents.begin(), menuComponents.end(), menuComponent);
}
MenuComponent* getChild(int i)
{
return menuComponents.at(i);
}
std::string getName()
{
return name;
}
std::string getDescription()
{
return description;
}
void print()
{
std::cout << "\n" + getName();
std::cout << ", " + getDescription()<<std::endl;
std::cout << "---------------------" << std::endl;
std::vector<MenuComponent*>::iterator it = menuComponents.begin();
while (it != menuComponents.end())
{
MenuComponent* menuComponent = *it;
it++;
menuComponent->print();
}
}
~Menu(){}
};
/*MenuItem.h*/
#pragma once
#include "MenuComponent.h"
#include <string>
#include <iostream>
class MenuItem : public MenuComponent
{
private:
std::string name;
std::string description;
bool vegetarian;
float price;
public:
//MenuItem(std::string name,std::string description,bool vegetarian,float price)
//{
// this->name = name;
// this->description = description;
// this->vegetarian = vegetarian;
// this->price = price;
//}
MenuItem(std::string _name, std::string _description, bool _vegetarian, float _price):
name(_name), description(_description), vegetarian(_vegetarian), price(_price){}
~MenuItem(){}
std::string getName()
{
return name;
}
std::string getDescription()
{
return description;
}
float getPrice()
{
return price;
}
bool isVegetarian()
{
return vegetarian;
}
void print()
{
std::cout << " " + getName();
if (isVegetarian())
{
std::cout << "(V)";
}
std::cout << ", " << getPrice()<<std::endl;
std::cout << " --" + getDescription() << std::endl;
}
};
/*UnsupportedOperationException.h*/
#pragma once
#include <exception>
#include <string>
class UnsupportedOperationException : public std::exception
{
private:
std::string message;
public:
UnsupportedOperationException() : std::exception() {}
UnsupportedOperationException(const std::string _message) :
std::exception(_message.c_str()), message(_message) {}
~UnsupportedOperationException(){}
std::string getMessage() const
{
return message;
}
};
/*Watress.h*/
#pragma once
#include "MenuComponent.h"
class Watress
{
private:
MenuComponent* allMenu;
public:
Watress(MenuComponent* _allMenu) : allMenu(_allMenu){}
void printMenu()
{
allMenu->print();
}
~Watress(){};
};
主函数:
#include "stdafx.h"
#include "MenuComponent.h"
#include "Menu.h"
#include "MenuItem.h"
#include "Watress.h"
int main()
{
MenuComponent* pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast");
MenuComponent* dinerMenu = new Menu("DINER MENU", "Lunch");
MenuComponent* cafeMenu = new Menu("CAFE MENU", "Diner");
MenuComponent* dessertMenu = new Menu("DESSERT MENU", "Desert of course");
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", "Pancake with fried eggs, sausage", false, 2.99));
pancakeHouseMenu->add(new MenuItem("Blueberry Pancake", "Pancake made with fresh blueberries", true, 3.49));
pancakeHouseMenu->add(new MenuItem("Waffles", "Waffles, with your cchoice of blueberries or strawberries", true, 3.59));
dinerMenu->add(new MenuItem("Vegtarian BLT", "(Fakin) Bacon with lettuce & tomato on whole wheat", true, 2.99));
dinerMenu->add(new MenuItem("BLT", "Bacon with lettuce & tomato on while wheat", false, 2.99));
dinerMenu->add(new MenuItem("Soup of the day", "Soup of the day,with a side of potato aalad", 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 flkey crust,topped with vanila ice cream",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 ascoop 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, salse, guacamol", true, 4.29));
Watress* waitress = new Watress(allMenus);
waitress->printMenu();
return 0;
}
参考文献:《Head Firs他设计模式》