Renbobo's Blog

Wo go where our vision is.

View project on GitHub

迭代器模式与组合模式

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;
}