29 Aug 2017
迭代器模式 提供一种方法顺序地访问一个局部对象中的各个元素,而又不暴露其内部的表示。 迭代器模式把元素之间游走的任务交给迭代器,而不是局和对象。这不仅让局和对象的接口和实现更为简洁,也可以让聚合更专注于它应该专注的事情上面,而不是遍历的事情。
例如,想要一个服务员分别说出正餐点和煎饼店的菜单,由于餐馆和煎饼店存储彩带的结构不同,因此在不接触具体实现的情况下,想要服务员读取到每一家店的所有餐品,需要一个迭代器来实现。
#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; }