11. 迭代器模式

来源:互联网 发布:淘宝qps 编辑:程序博客网 时间:2024/06/04 19:27

      利用相同接口可以遍历不同集合(聚集),且不暴露集合内部的元素。 

      书中的例子:A餐厅和B餐厅合并,他们的菜单拥有不同的存储方法,如A餐厅用数组array,而B餐厅用list。这样带来的问题是在打印菜单项的时候需要分别遍历他们各种的菜单,这样处理不仅麻烦,而且不利于扩展,当有更多的餐厅被合并的时候,会带来更多的代码修改。如果是将各个餐厅的菜单改为同一种容器来存放,这样带来的改动过大。所以结合各种利弊,这里采取的解决方法是将各自菜单的遍历方式统一化。 


1. 基本实现 

class Waiter{pubic:     Waiter(MenuA *a, MenuB *b);     void PrintMenu();     void PrintMenu(Iterator *it);     public:     menu *m_pMenuA;     menu *m_pMenuB;};Waiter::Waiter(MenuA *a, MenuB *b){     m_pMenuA = a;     m_pMenuB = b;    }void Waiter::PrintMenu(){     Iterator *ita = m_pMenuA->CreateIterator();     Iterator *itb = m_pMenuB->CreateIterator();     PrintMenu(ita);     PrintMenu(itb);   }void Client::PrintMenu(Iterator *it){     while(it->HasNext())     {          Object *pObj = it->Next();          pObj->printMenu();     }}
client:MenuA *pMenuA = new MenuA();MenuB *pMenuB = new MenuB();Waiter *pWaiter = new Waiter(pMenuA, pMenuB);pWaiter->PrintMenu();

2. 更近一步 

      按照上面的方法,对于菜单很多的情况下,writer就要创建更多的迭代器,并分别PrintMenu。解决多个菜单更好的解决方法是在菜单的外层嵌套一个迭代器,所以先将各个菜单放入一个容器中,并为这个容器定义迭代器,在打印菜单的时候利用这个迭代器遍历容器。
class Waiter{public:     Waiter(ArrayMenus *menus) : m_menus(menus) {}     void PrintMenus();     void PrintMenus(Iterartor *it);public:     ArrayMenus *m_menus;     // 存放菜单};void Waiter::PrintMenus(){     Iterator *menuIter = m_menus.iterator();     while(menuIter->HasNext())     {          Menus *pMenu = menuIter->Next();     // 从菜单聚集中取得菜单          PrintMenus(pMenu->CreateIteraror());       // 打印菜单中所有的菜单项     }}void Waiter::PrintMenus(Iterartor *it){     while(it->HasNext())     {          MenuItem *item = it->Next();          item->Print();     }}
client:ArrayMenus *pMenus = new ArrayMenus();MenuA *pMenuA = new MenuA();MenuB *pMenuB = new MenuB();pMenus->Add(pMenuA);pMenus->Add(pMenuB);Waiter *pWaiter = new Waiter(pMenus);pWaiter->PrintMenu();





原创粉丝点击