迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。
迭代器模式的类图如下:(图片摘自Head First 设计模式)
代码实现如下:
/*MenuItem.h*/
#pragma once
#include <string>
using namespace std;
class MenuItem
{
private:
string name;
string description;
bool vegetarian;
float price;
public:
MenuItem(){}
MenuItem(string name,string description,bool vegetarian,float price)
{
this->name = name;
this->description = description;
this->vegetarian = vegetarian;
this->price = price;
}
string getName()
{
return name;
}
string getDescription()
{
return description;
}
float getPrice()
{
return price;
}
bool isvegetarian()
{
return vegetarian;
}
~MenuItem();
};
/*Menu.h*/
#pragma once
#include "Iterator.h"
#include "MenuItem.h"
class Menu
{
public:
Menu(){}
virtual ~Menu(){}
virtual Iterator<MenuItem>* createIterator() = 0;
};
/*DinerMenu.h*/
#pragma once
#include "MenuItem.h"
#include "Menu.h"
#include "DinerMenuIterator.h"
#include "Iterator.h"
#include <iostream>
#include <string>
class DinerMenu : public Menu
{
private:
static const int MAX_ITEMS = 6;
int numberOfItems;
MenuItem** menuItems;
public:
//DinerMenu(){}
DinerMenu() : numberOfItems(0)
{
menuItems = new MenuItem*[MAX_ITEMS+1];
//初始化为0
for (int i = 0; i <= MAX_ITEMS; ++i)
{
menuItems[i] = 0;//hasNext()才不会出错
}
addItem("Vegtarian BLT","(Fakin) Bacon with lettuce & tomato on whole wheat",true, 2.99);
addItem("BLT","Bacon with lettuce & tomato on while wheat",false,2.99);
addItem("Soup of the day","Soup of the day,with a side of potato aalad",false,3.29);
addItem("Hotdog","A hot dog,with saurkraut, relish, onions, topped with cheese",false,3.05);
addItem("Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99);
addItem("Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89);
}
void addItem(string name, string description,bool vevetarian, float price)
{
MenuItem* menuItem = new MenuItem(name, description, vevetarian, price);
if (numberOfItems>=MAX_ITEMS)
{
std::cerr << "Sorry,menu id full! Can't add item to menu" << endl;
}
else
{
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}
MenuItem** getMenuItems()
{
return menuItems;
}
Iterator<MenuItem>* createIterator()
{
Iterator<MenuItem>* it = new DinerMenuIterator(menuItems);
return it;
}
~DinerMenu(){}
};
/*PancakeHouseMenu.h*/
#pragma once
#include <string>
#include <vector>
#include "MenuItem.h"
#include "Iterator.h"
#include "PancakeHouseMenuIterator.h"
using namespace std;
class PancakeHouseMenu
{
private:
vector<MenuItem*> menuItems;
public:
PancakeHouseMenu(){
addItem("K&B's Pancake Breakfast","Pancakes with scrambled eggs, and toast",true,2.99);
addItem("Regular Pancake Breakfast","Pancake with fried eggs, sausage",false,2.99);
addItem("Blueberry Pancake","Pancake made with fresh blueberries",true,3.49);
addItem("Waffles","Waffles, with your cchoice of blueberries or strawberries",true,3.59);
}
void addItem(string name, string description, bool vegetarian, float price)
{
MenuItem* menuItem = new MenuItem(name,description,vegetarian,price);
menuItems.push_back(menuItem);
}
vector<MenuItem*> getMemeItems()
{
return menuItems;
}
Iterator<MenuItem>* createIterator()
{
Iterator<MenuItem>* it = new PancakeHouseMenuIterator(menuItems);
return it;
}
~PancakeHouseMenu(){}
};
/*Iterator.h*/
#pragma once
template <class T>
class Iterator
{
public:
Iterator(){}
virtual ~Iterator(){}
virtual bool hasNext() = 0;
virtual T* next() = 0;
};
/*DinerMenuIterator.h*/
#pragma once
#include "Iterator.h"
#include "MenuItem.h"
class DinerMenuIterator : public Iterator<MenuItem>
{
private:
MenuItem** items;
int position;
public:
DinerMenuIterator(MenuItem** _items):items(_items),position(0){}
MenuItem* next()
{
MenuItem* menuItem = items[position];
position++;
return menuItem;
}
bool hasNext()
{
if (items[position] == 0)
return false;
else
return true;
}
~DinerMenuIterator(){}
};
/*PancakeHouseMenuIterator.h*/
#pragma once
#include "Iterator.h"
#include "MenuItem.h"
#include <vector>
class PancakeHouseMenuIterator : public Iterator<MenuItem>
{
private:
std::vector<MenuItem*> items;
int position;
public:
PancakeHouseMenuIterator(std::vector<MenuItem*> _items):items(_items),position(0){}
MenuItem* next()
{
MenuItem* menuItem = items[position];
position++;
return menuItem;
}
bool hasNext()
{
if (position>=items.size())
return false;
else
return true;
}
~PancakeHouseMenuIterator(){}
};
主函数
#include "stdafx.h"
#include "DinerMenu.h"
#include "PancakeHouseMenu.h"
#include <iostream>
#include <vector>
#include "Waitress.h"
using namespace std;
int main()
{
PancakeHouseMenu* pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu* dinerMenu = new DinerMenu();
Waitress* waitress = new Waitress(pancakeHouseMenu, dinerMenu);
waitress->printMenu();
delete waitress;
delete dinerMenu;
delete pancakeHouseMenu;
return 0;
}
运行结果如下:
参考文献:《Head First 设计模式》