首页 > 代码库 > 迭代器与组合模式

迭代器与组合模式

迭代模式与组合模式要点

      1.迭代器允许访问聚合的元素,而不需要暴露它的内部结构

      2.迭代器将遍历聚合的工作封装进一个对象中

      3.当使用迭代器的时候,我们一来聚合提供遍历

      4.迭代器提供了一个通用的接口,让我们遍历聚合的项时,就可以使用多态机制

      5.我们应该努力让一个类只分配一个责任

      6.组合模式提供一个结构,可同时包容个别对象和组合对象

      7.组合模式允许客户对个别对象以及组合对象一视同仁

      8.组合结构内的任意对象称为组件,组件可以使组合,也可以是叶子节点

      9.在实现组合模式时,有许多设计上的折衷。你要根据需要平衡透明性和安全性

好处:

  1. 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别
  2. 简化了容器的接口。但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口
  3. 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的

由此也能得出迭代器模式的适用范围
  1. 访问一个容器对象的内容而无需暴露它的内部表示
  2. 支持对容器对象的多种遍历

  3. 为遍历不同的容器结构提供一个统一的接口(多态迭代)

意义:这个模式给你提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。在设计中使用迭代器的影响是明显的:如果你有一个统一的方法访问聚合中的每一个对象,你就可以编写多态的代码和这些聚合搭配,使用---如同前面的printMenu()方法一样,只要有了迭代器这个方法根本不管菜单项究竟是由数组还是有ArrayList来保存。另一个对设计造成重要影响的,是迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注它所应该专注的事情上面来。



#include <iostream>

#include <cstdlib>
#include <vector>
using namespace std;

class MenuComponent
{
    public:
    virtual ~MenuComponent(){}
    virtual void add(MenuComponent *m){}
    virtual void print()=0;
    virtual string getDescription()=0;
    virtual string getName()=0;
    virtual void remove(MenuComponent *m){}
    virtual MenuComponent* getChild(int i){}
};
class MenuItem :public MenuComponent
{
    private:
    string name;
    string description;
    bool vegetarain;
    double price;
    public:
    ~MenuItem(){}
    MenuItem(string n,string d,bool ve,double p)
    {
        name=n;
        description=d;
        vegetarain=ve;
        price=p;
    }
    string getName()
    {
        return name;
    }
    string getDescription()
    {
        return description;
    }
    double getPrice()
    {
        return price;
    }
    bool isVegetarian()
    {
        return vegetarain;
    }
    void print()
    {
        cout<<" "+getName();
        if(isVegetarian())
        {
            cout<<"(v)";
        }
        cout<<", "<< getPrice();
        cout<<"   --"+getDescription()<<endl;
    }
};
class Menu:public MenuComponent
{
private:
  vector<MenuComponent*> menucomponents;
  string name;
  string description;
  public:
  ~Menu(){}
  Menu(string n,string d)
  {
      name=n;
      description=d;
  }
  void add(MenuComponent *m)
  {
     menucomponents.push_back(m);
  }
  void remove(MenuComponent *m)
  {
    vector<MenuComponent*>::iterator iter;
    int i=0;
    for(iter=menucomponents.begin();iter!=menucomponents.end(),i<menucomponents.size();i++,iter++)
    {
        if(m->getChild(i)==(*iter))
        {
            menucomponents.erase(iter);
        }
        if(m==(*iter))
        {
            menucomponents.erase(iter);
        }
    }
  }
  MenuComponent *getChild(int i)
  {
     return menucomponents[i];
  }
  string getName()
  {
      return name;
  }
  string getDescription()
  {
      return description;
  }
  void print()
  {
      cout<<"\n  "+getName();
      cout<<", "+getDescription()<<endl;
      cout<<"--------------------------------"<<endl;
      vector<MenuComponent*>::iterator iter=menucomponents.begin();
      for(;iter!=menucomponents.end();iter++)
      {
          (*iter)->print();
      }
  }
};
class Waitress
{
    MenuComponent *allMenus;
    public:
    ~Waitress(){}
    Waitress(MenuComponent *all)
    {
        this->allMenus=all;
    }
    void printMenu()
    {
        allMenus->print();
    }
};


int main()
{
   MenuComponent *pancakeHouseMenu=new Menu("Pancake house menu","breakfast");
   MenuComponent *dinerMenu=new Menu("dinerMenu","lunch");
   MenuComponent *cafeMenu=new Menu("cafeMenu","Dinner");
   MenuComponent *dessertMenu=new Menu("dessertMenu","dessert of course");
   MenuComponent *allMenus=new Menu("All Menus","All menus combined");
   allMenus->add(pancakeHouseMenu);
   pancakeHouseMenu->add(new MenuItem("K&B‘s Pancake Breadfaset","Pancakes with fried eggs,and toast",true,2.99));
   //allMenus->remove(pancakeHouseMenu);
   allMenus->add(dinerMenu);
   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 ice cream",true,1.59));
  // allMenus->remove(dessertMenu);
   allMenus->remove(dinerMenu);
   Waitress *waitress=new Waitress(allMenus);
   waitress->printMenu();
   return 0;
}