迭代器模式与组合模式
迭代器模式 提供一种方法顺序地访问一个局部对象中的各个元素,而又不暴露其内部的表示。 迭代器模式把元素之间游走的任务交给迭代器,而不是局和对象。这不仅让局和对象的接口和实现更为简洁,也可以让聚合更专注于它应该专注的事情上面,而不是遍历的事情。
例如,想要一个服务员分别说出正餐点和煎饼店的菜单,由于餐馆和煎饼店存储彩带的结构不同,因此在不接触具体实现的情况下,想要服务员读取到每一家店的所有餐品,需要一个迭代器来实现。
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//每一个菜单项的定义
class MenuItem {
public:
MenuItem(string name,string description,bool vegetarian,double price){
this->name = name;
this->description = description;
this->vegetarian = vegetarian;
this->price = price;
}
~MenuItem(){}
string getName(){
return name;
}
string getDescription(){
return description;
}
double getPrice(){
return price;
}
bool isVegetarian(){
return vegetarian;
}
public:
string name;
string description;
bool vegetarian;
double price;
};
//迭代器及其子类
template <typename T>
class Iterator{
public:
Iterator(){}
virtual ~Iterator(){}
virtual bool hasNext() = 0;
virtual T Next() = 0;
};
class DinerMenuIterator : public Iterator<MenuItem>{
public:
DinerMenuIterator(vector<MenuItem> menuItem1){
this->menuItem = menuItem1;
position = 0;
}
~DinerMenuIterator(){}
virtual bool hasNext(){
if (position >= menuItem.size() || menuItem.empty())
return false;
else
return true;
}
virtual MenuItem Next(){
return this->menuItem[position++];
}
public:
vector<MenuItem> menuItem;
size_t position;
};
class LunchMenuIterator : public Iterator<MenuItem>{
public:
LunchMenuIterator(list<MenuItem> menuItem1){
this->menuItem = menuItem1;
position = 0;
}
~LunchMenuIterator(){}
virtual bool hasNext(){
if (position >= menuItem.size() ||menuItem.empty())
return false;
else
return true;
}
virtual MenuItem Next(){
list<MenuItem> tmp = this->menuItem;
size_t tmp_poistion = position;
while(tmp_poistion-- > 0){
tmp.pop_front();
}
position++;
return tmp.front();
}
public:
list<MenuItem> menuItem;
size_t position;
};
//菜单及其子类
class Menu{
public:
Menu(){}
virtual ~Menu(){}
virtual Iterator<MenuItem>* createIterator() = 0;
};
class DinerMenu : public Menu{
public:
DinerMenu(){
addItem("Vegetarian BLT","(Fakin)Bacon with lettuce & tomato on whole wheat",true,2.99);
addItem("BLT","Bacon withe lettuce & tomato on whole wheat",false,2.00);
addItem("Soup of the day","Soup of the day,with a side of potato salad",false,3.29);
addItem("A hot dog","A hot dog,with saurkraut,relish,onions,topped with cheese",false,3.05);
}
virtual ~DinerMenu(){}
virtual Iterator<MenuItem>* createIterator(){
Iterator<MenuItem>* dinerMenuIterator = new DinerMenuIterator(menuItem);
return dinerMenuIterator;
}
void addItem(string name,string description,bool vegetarian,double price){
MenuItem item(name,description,vegetarian,price);
menuItem.push_back(item);
}
public:
vector<MenuItem> menuItem;
};
class PancakeMenu : public Menu{
public:
PancakeMenu(){
addItem("K&B's Pancake","Pancakes with scrambled eggs,and toast",true,2.99);
addItem("Regular Pancake","Pancake with fried eggs,sausage",false,2.00);
addItem("BlueBerry Pancake","Pancake made with fresh blueberries",false,3.49);
addItem("Waffle","Pancake with your choice of blueerries or strawberries",false,3.59);
}
virtual ~PancakeMenu(){}
virtual Iterator<MenuItem>* createIterator(){
Iterator<MenuItem>* lunchMenuIterator = new LunchMenuIterator(menuItem);
return lunchMenuIterator;
}
void addItem(string name,string description,bool vegetarian,double price){
MenuItem item(name,description,vegetarian,price);
menuItem.push_back(item);
}
public:
list<MenuItem> menuItem;
};
//服务员(聚合类)及测试代码
class Waitress{
public:
Waitress(Menu* dinermenu,Menu* pancakeMenu){
this->dinerMenu = dinermenu;
this->pancakeMenu = pancakeMenu;
}
~Waitress(){}
void printMenu(){
Iterator<MenuItem>* dineriterator = dinerMenu->createIterator();
printMenu(dineriterator);
Iterator<MenuItem>* pancakeiterator = pancakeMenu->createIterator();
printMenu(pancakeiterator);
}
void printMenu(Iterator<MenuItem>* iter){
while(iter->hasNext()){
MenuItem menuItem = iter->Next();
cout << "name:"<< menuItem.getName() << endl;
cout << "description:"<< menuItem.getDescription() << endl;
cout << "price:"<<menuItem.getPrice() << endl;
cout << "----------------------------------------" << endl;
}
}
public:
Menu* dinerMenu;
Menu* pancakeMenu;
};
int main(){
Menu* dinerMenu = new DinerMenu();
Menu* pancakeMenu = new PancakeMenu();
Waitress waitress(dinerMenu,pancakeMenu);
waitress.printMenu();
return 1;
}