迭代器模式 Iterator,组合模式 Composite -- 学习HeadFirst设计模式记录

 

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

组合模式   :允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。


单一原则:一个类应该只有一个引起变化的原因。


迭代器模式示例代码:
  
#include <iostream>
#include <iomanip>   //  cout格式控制
#include < string>
#include <vector>


class MenuItem;

/* 迭代器接口 */
class Iterator
{
public:
    virtual bool HasNext() = 0;
    virtual void* Next() = 0;
};

/* PancakeMenu 迭代器 */
class PancakeMenuIterator : public Iterator
{

public:
    PancakeMenuIterator(std::vector<MenuItem*>* vMenuItem) : _vMenuItem(vMenuItem), _nCurrPos( 0)
    {}
    
     virtual  bool HasNext()
    {
         if (_nCurrPos < _vMenuItem->size())
             return  true;
         else
             return  false;
    }
     virtual  void* Next()
    {
         return _vMenuItem->at(_nCurrPos++);
    }
    
private:
    std::vector<MenuItem*>* _vMenuItem;
     int _nCurrPos;
};
/* DinerMenu 迭代器 */
class DinerMenuIterator : public Iterator
{

public:
    DinerMenuIterator(MenuItem **menuItems,  int num) : _menuItems(menuItems), _itemsNum(num), _nCurrPos( 0)
    {}
    
     virtual  bool HasNext()
    {
         if (_nCurrPos < _itemsNum)
             return  true;
         else
             return  false;
    }
     virtual  void* Next()
    {
         return _menuItems[_nCurrPos++];
    }
    
private:
    MenuItem ** _menuItems;
     int _itemsNum;
     int _nCurrPos;
};


/*  菜单项  */
class MenuItem
{
public:
    MenuItem(std:: string name, std:: string description,  bool vegetarian,  double price)
        : _name(name), _description(description), _vegetarian(vegetarian), _price(price)
    {}
    
    std:: string GetName()        {  return _name; }
    std:: string GetDescription() {  return _description; }
     bool IsVegetarian()          {  return _vegetarian; }
     double GetPrice()            {  return _price; }

private:
    std:: string _name;
    std:: string _description;
     bool        _vegetarian;
     double      _price;
};
/*  菜单 Pancake:薄烤饼  */
class PancakeHouseMenu
{
public:
    PancakeHouseMenu()
    {
        AddItem( " K&B Pancake Breakfast ",      " Pancakes with scrambled eggs and toast "true2.99);
        AddItem( " Regular Pancake Breakfast "" Pancakes with fried eggs sausage ",        false2.99);
        AddItem( " Blueberry Pancakes ",         " Pancakes made with fresh blueberries ",    true,   3.49);
        AddItem( " Waffles ",                    " Waffles with your choice of blueberries or strawberries "true3.59);
    }

     void AddItem(std:: string name, std:: string description,  bool vegetarian,  double price)
    {
        MenuItem *pItem =  new MenuItem(name, description, vegetarian, price);
        _vMenuItem.push_back(pItem);
    }

     PancakeMenuIterator* GetIterator()  { return new PancakeMenuIterator(&_vMenuItem);}

    std::vector<MenuItem*>* GetMenus()  {  return &_vMenuItem; }

private:
    std::vector<MenuItem*> _vMenuItem;
};
/*  菜单 Diner:路边小饭店,餐车式简便餐厅  */
class DinerMenu
{
public:
    DinerMenu()
    {
        _aMenuItems =  new MenuItem *[MAX_ITEMS];
        _num =  0;

        AddItem( " vegetarian BLT ",   " (Fakin') Bacon with lettuce & tomato on whole wheat "true2.99);
        AddItem( " BLT ",              " -- "false2.99);
        AddItem( " Soup of the day "" -- "false3.29);
        AddItem( " Hotdoy ",           " -- "false3.05);
    }

     void AddItem(std:: string name, std:: string description,  bool vegetarian,  double price)
    {
         if (_num < MAX_ITEMS)
        {
            MenuItem *pItem =  new MenuItem(name, description, vegetarian, price);
            _aMenuItems[_num] = pItem;
            _num ++;
        }
         else
        {
            std::cout<< " Sorry, menu is full. Can't add item to menu. "<<std::endl;
        }
    }

    MenuItem **GetMenus()  {  return _aMenuItems; }

     DinerMenuIterator* GetIterator()  {  return new DinerMenuIterator(_aMenuItems, _num);}

private:
     static  const  int MAX_ITEMS;
    MenuItem **_aMenuItems;
     int _num;
};
const  int DinerMenu::MAX_ITEMS =  10;

/*  服务员,遍历显示菜单  */
class Waitress
{
public:
    Waitress(PancakeHouseMenu *pancakeMenu, DinerMenu *dinerMenu)
        :_pancakeMenu(pancakeMenu), _dinerMenu(dinerMenu)
    {}

     void PrintMenu()
    {
        DinerMenuIterator *dinerIt = _dinerMenu->GetIterator();
        PancakeMenuIterator* pancakeIt = _pancakeMenu->GetIterator();

        std::cout<< " == Diner menu "<<std::endl;
        PrintMenu(dinerIt);
        std::cout<< " == Pancake menu "<<std::endl;
        PrintMenu(pancakeIt);
    }

     void PrintMenu(Iterator *it)
    {
         #define COUT_STR_FORMAT(width)   std::setw(width)<<std::setiosflags(std::ios::left)

        MenuItem* item = NULL;

        std::cout<<COUT_STR_FORMAT( 20)<< " -name- "<< "    "<<COUT_STR_FORMAT( 20)<< " -Description- "<<std::endl;
         while(it->HasNext())
        {
            item = (MenuItem *)it->Next();
            std::cout<<COUT_STR_FORMAT( 20)<<item->GetName().c_str()<< "    "<<COUT_STR_FORMAT( 20)<<item->GetDescription().c_str()<<std::endl;
        }
    }

private:
    PancakeHouseMenu *_pancakeMenu;
    DinerMenu        *_dinerMenu;
};

int main()
{
    std::cout<< " Iterator patten. "<<std::endl<<std::endl;

    PancakeHouseMenu *pancakeMenu =  new PancakeHouseMenu();
    DinerMenu        *dinerMenu   =  new DinerMenu();

    Waitress waitess(pancakeMenu, dinerMenu);
    waitess.PrintMenu();

     return  0;
}

   

 组合模式示例代码:

#include <iostream>
#include <iomanip>   //  cout格式控制
#include < string>
#include <vector>

/* 菜单组合接口 */
class MenuComponent
{

public:
     /*  组合的3个基本方法  */
     virtual  void Add(MenuComponent *menu)    {}
     virtual  void Remove(MenuComponent *menu) {}
     virtual MenuComponent *GetChild( int i)   {  return NULL; }
    
     /*  菜单项方法  */
     virtual std:: string GetName()        {  return  ""; }
     virtual std:: string GetDescription() {  return  ""; }
     virtual  bool IsVegetarian()          {  return  false; }
     virtual  double GetPrice()            {  return  0; }
    
    /* 组合接口的操作,菜单和菜单项 同时支持 */
    virtual void Print()  {}
};

#define COUT_STR_FORMAT(width)   std::setw(width)<<std::setiosflags(std::ios::left)
/*  菜单项  */
class MenuItem :  public MenuComponent
{
public:
    MenuItem(std:: string name, std:: string description,  bool vegetarian,  double price)
        : _name(name), _description(description), _vegetarian(vegetarian), _price(price)
    {}
    
    std:: string GetName()        {  return _name; }
    std:: string GetDescription() {  return _description; }
     bool IsVegetarian()          {  return _vegetarian; }
     double GetPrice()            {  return _price; }

    /* 组合接口的操作,菜单和菜单项 同时支持 */
    void Print()
    {
        std::cout<<COUT_STR_FORMAT(20)<<_name.c_str()<<"  "<<COUT_STR_FORMAT(20)<<_description.c_str()<<std::endl;
    }


private:
    std:: string _name;
    std:: string _description;
     bool        _vegetarian;
     double      _price;
};
class Menu :  public MenuComponent
{
public:
    Menu(std:: string name, std:: string description) : _name(name), _description(description)
    {}

     /*  组合的3个基本方法  */
     void Add(MenuComponent *menu)    { _vMenuItem.push_back(menu); }
     void Remove(MenuComponent *menu) 
    {
         for(std::vector<MenuComponent*>::iterator it=_vMenuItem.begin(); it!=_vMenuItem.end(); )
        {
             if(*it == menu)
            {
                it = _vMenuItem.erase(it);    // _vMenuItem.erase(it);
            }
             else
            {
                ++it;
            }
        }
    }
    MenuComponent *GetChild( int i)   {  return _vMenuItem.at(i); }

    std:: string GetName()        {  return _name; }
    std:: string GetDescription() {  return _description; }

    /* 组合接口的操作,菜单和菜单项 同时支持 */
    void Print()
    {
        std::cout<<"menu:"<<_name.c_str()<<std::endl;

        std::vector<MenuComponent*>::iterator it = _vMenuItem.begin();
        while (it != _vMenuItem.end())
        {
            (*it)->Print();
            ++ it;
        }
    }


private:
    std:: string _name;
    std:: string _description;
    std::vector<MenuComponent*> _vMenuItem;
};

/*  服务员,显示菜单  */
class Waitress
{
public:
    Waitress()
    {
        Menu *dinerMenu =  new Menu( " Diner menu """);
        dinerMenu->Add( new MenuItem( " vegetarian BLT ",   " (Fakin') Bacon with lettuce & tomato on whole wheat "true2.99));
        dinerMenu->Add( new MenuItem( " BLT ",              " -- "false2.99));
        dinerMenu->Add( new MenuItem( " Soup of the day "" -- "false3.29));
        dinerMenu->Add( new MenuItem( " Hotdoy ",           " -- "false3.05));

        Menu *pancakeMenu =  new Menu( " Pancake menu """);
        pancakeMenu->Add( new MenuItem( " K&B Pancake Breakfast ",      " Pancakes with scrambled eggs and toast "true2.99));
        pancakeMenu->Add( new MenuItem( " Regular Pancake Breakfast "" Pancakes with fried eggs sausage ",        false2.99));
        pancakeMenu->Add( new MenuItem( " Blueberry Pancakes ",         " Pancakes made with fresh blueberries ",    true,   3.49));
        pancakeMenu->Add( new MenuItem( " Waffles ",                    " Waffles with your choice of blueberries or strawberries "true3.59));

        _allMenus =  new Menu( " All Menu """);
        _allMenus->Add(dinerMenu);
        _allMenus->Add(pancakeMenu);
    }

     void PrintMenu()
    {
        _allMenus->Print();
    }

private:
    Menu *_allMenus;
};

int main()
{
    std::cout<< " Composite patten. "<<std::endl<<std::endl;

    Waitress waitess;
    waitess.PrintMenu();

     return  0;
}
  

 

你可能感兴趣的:(iterator)