zoukankan      html  css  js  c++  java
  • 迭代器模式 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;
    }
      
  • 相关阅读:
    ASP.NET中常用的优化性能的方法
    把WinDbg集成到Visual Studio中
    提高ASP.net的性能
    Msn Library
    [转帖]OutOfMemoryException问题的处理
    一完美的关于请求的目录不存在而需要url重写的解决方案!
    在 ASP.NET 中执行 URL 重写
    转 内存不断上升处理方法
    IIS 6 通配符应用映射和HttpHandler配置
    Java开源
  • 原文地址:https://www.cnblogs.com/ant-wjf/p/4605520.html
Copyright © 2011-2022 走看看