目录
1. 封装遍历
因为早餐和午餐的遍历方式不同,这样在遍历菜单时由于不同的遍历方式不方便。
当我们对遍历进行封装就会对实现遍历的统一
2. 定义迭代器模式
通过类图我们可以知道:
Iterator是一个接口,通过实现接口内的方法达到遍历的标准
Aggregate是聚合的接口,通过对迭代器接口的引用实现对迭代器的解耦
Client通过对两边接口的引用实现了集合和迭代器的解耦
2.1 部分源码
2.1.1 MenuItem.h
#include <string>
using std::string;
class MenuItem{
public:
string name;
string description;
bool vegetarian;
double price;
MenuItem();
MenuItem(string name,string description,bool vegetarian,double price);
string getName();
string getDescription();
double getPrice();
bool isVegetarian();
string toString();
};
2.1.2 Menu.h
#include "Iterator.h"
class Menu{
public:
virtual Iterator *createIterator()=0;
virtual ~Menu(){};
};
2.1.3 Iterator.h
#include "MenuItem.h"
class Iterator{
public:
virtual bool hasNext()=0;
virtual MenuItem *next()=0;
virtual ~Iterator(){};
};
2.1.4 ArrayIterator.h
#include "Iterator.h"
#include "MenuItem.h"
class ArrayIterator:public Iterator{
public:
ArrayIterator(MenuItem items[],int size);
virtual MenuItem *next()override final;
virtual bool hasNext()override final;
virtual ~ArrayIterator();
private:
MenuItem *items;
int position=0;
int size=0;
};
2.1.5 ArrayIterator.cpp
#include "ArrayIterator.h"
ArrayIterator::ArrayIterator(MenuItem items[], int size)
{
this->items=items;
this->size=size;
}
MenuItem *ArrayIterator::next()
{
return &items[position++];
}
bool ArrayIterator::hasNext()
{
if(position>=size)return false;
else return true;
}
ArrayIterator::~ArrayIterator()
{
}
2.1.6 DinerMenu.h
#include "Menu.h"
#include "MenuItem.h"
#include "Iterator.h"
#include "ArrayIterator.h"
class DinerMenu:public Menu{
public:
DinerMenu();
void addItem(string name,string description,bool vegetarian, double price);
MenuItem *getMenuItems();
virtual Iterator *createIterator()override final;
virtual ~DinerMenu();
private:
int numberOfItems=0;
MenuItem *menuItems;
};
2.1.7 DinerMenu.cpp
#include "DinerMenu.h"
#include "iostream"
int MAX_ITEMS = 6;
DinerMenu::DinerMenu()
{
menuItems=new MenuItem[MAX_ITEMS];
menuItems[0]=MenuItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
menuItems[1]=MenuItem("BLT",
"Bacon with lettuce & tomato on whole wheat", false, 2.99);
menuItems[2]=MenuItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29);
menuItems[3]=MenuItem("Hotdog",
"A hot dog, with sauerkraut, relish, onions, topped with cheese",
false, 3.05);
menuItems[4]=MenuItem("Steamed Veggies and Brown Rice",
"Steamed vegetables over brown rice", true, 3.99);
menuItems[5]=MenuItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
numberOfItems=6;
}
void DinerMenu::addItem(std::string name, std::string description, bool vegetarian, double price)
{
MenuItem menuItem=MenuItem(name,description,vegetarian,price);
if(numberOfItems>=MAX_ITEMS){
std::cout<<"Sorry, menu is full! Can't add item to menu"<<std::endl;
}else{
menuItems[numberOfItems]=menuItem;
numberOfItems++;
}
}
MenuItem *DinerMenu::getMenuItems()
{
return menuItems;
}
Iterator *DinerMenu::createIterator()
{
return new ArrayIterator(menuItems,numberOfItems);
}
DinerMenu::~DinerMenu()
{
}
3. 单一责任
如果允许一个类既要管理集合又要提供遍历,当集合改变需要改变类,当遍历改变也要改变类,所以尽量使一个类只有一个责任
4. 定义组合模式
在前面我们都是一个菜单一个菜单独立出来的,但是当我们菜单中又要嵌套菜单这咋办?
组合模式就是定义一个超类,两个具体类继承,一个类可以嵌套超类就相当于菜单(这样就可以嵌套菜单也可以嵌套菜单项),另一个就是具体的菜单项
4.1 类图和部分源码
4.1.1 MenuComponent.h
#include <string>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class MenuComponent{
public:
virtual void add(MenuComponent *menuComponent);
virtual void remove(MenuComponent *menuComponent);
virtual MenuComponent *getChild(int i);
virtual string getName();
virtual string getDescription();
virtual double getPrice();
virtual bool isVegetarian();
virtual void print();
virtual ~MenuComponent();
};
4.1.2 MenuItem.h
#include "MenuComponent.h"
class MenuItem:public MenuComponent{
public:
MenuItem(string name,string description,bool vegetarian,double price);
virtual string getName()override final;
virtual string getDescription()override final;
virtual double getPrice()override final;
virtual bool isVegetarian()override final;
virtual void print()override final;
virtual ~MenuItem();
private:
string name;
string description;
bool vegetarian;
double price;
};
4.1.3 Menu.h
#include "MenuComponent.h"
class Menu:public MenuComponent{
public:
Menu(string name,string description);
virtual void add(MenuComponent *menuComponent)override final;
virtual void remove(MenuComponent *menuComponent)override final;
virtual MenuComponent *getChild(int i)override final;
virtual string getName()override final;
virtual string getDescription()override final;
virtual void print()override final;
virtual ~Menu();
private:
string name;
string description;
vector<MenuComponent *> menuComponents;
};
4.1.4 Waitress.h
#include "MenuComponent.h"
class Waitress{
public:
Waitress(MenuComponent *allMenus);
void printMenu();
virtual ~Waitress();
private:
MenuComponent *allMenus;
};
4.1.5 main.cpp
#include <iostream>
#include "MenuComponent.h"
#include "Menu.h"
#include "Waitress.h"
#include "MenuItem.h"
using namespace std;
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(
"Hot Dog",
"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;
}
5. 组合迭代器