迭代器模式,组合模式 -- 学习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", true, 2.99);
        AddItem("Regular Pancake Breakfast", "Pancakes with fried eggs sausage",       false, 2.99);
        AddItem("Blueberry Pancakes",        "Pancakes made with fresh blueberries",   true,  3.49);
        AddItem("Waffles",                   "Waffles with your choice of blueberries or strawberries", true, 3.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", true, 2.99);
        AddItem("BLT",             "--", false, 2.99);
        AddItem("Soup of the day", "--", false, 3.29);
        AddItem("Hotdoy",          "--", false, 3.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", true, 2.99));
        dinerMenu->Add(new MenuItem("BLT",             "--", false, 2.99));
        dinerMenu->Add(new MenuItem("Soup of the day", "--", false, 3.29));
        dinerMenu->Add(new MenuItem("Hotdoy",          "--", false, 3.05));

Menu *pancakeMenu = new Menu("Pancake menu", "");
        pancakeMenu->Add(new MenuItem("K&B Pancake Breakfast",     "Pancakes with scrambled eggs and toast", true, 2.99));
        pancakeMenu->Add(new MenuItem("Regular Pancake Breakfast", "Pancakes with fried eggs sausage",       false, 2.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", true, 3.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;
}

时间: 2024-10-03 22:45:47

迭代器模式,组合模式 -- 学习HeadFirst设计模式记录的相关文章

模版方法模式Template Mothod -- 学习HeadFirst设计模式记录

模版方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 这个模式主要用来创建一个算法的模版. 好莱坞原则:别调用(打电话)我们,我们会调用(打电话)你: 应用案例: 数组排序算法 void sort(Object[] a),其中入参对象必须实现compareTo(Object o)方法,即入参对象必须实现Comparable接口. 模式演示 代码: #include <iostream> /* caffe

策略模式 -- 学习HeadFirst设计模式记录

策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 将算法族从对象中独立出来,然后在对象中通过组合的方式,定义算法对象,再委托该对象处理算法. 单一原则:封装变化: 多用组合,少用继承: 针对接口编程,不针对实现编程:

复合模式Compound -- 学习HeadFirst设计模式记录

? 复合模式:结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题. ? 典型应用:MVC模式,M:Model, V:View, C:Controller.类似的还有Web:浏览器/服务器模型. ? ?

状态模式 -- 学习HeadFirst设计模式记录

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类. 面向过程方法:针对动作,在处理时switch/if-else各个状态,然后分别处理: #include <iostream> class GumballMachine{public:    GumballMachine()    {        _count = 100;        _state = NO_QUARTER;    } /* 执行一个动作时,switch/if-else处理所有的状态 */    

命令模式– 学习HeadFirst设计模式记录

命令模式:将"请求"分装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 命令模式的核心是实现Command基类.将控制各个家电的控制类,都继承自Command类,并实现execute方法.然后,遥控器上的各个按钮就可以通过多态,使用Command类型的指针调用execute来控制各个家电了. class Command{public:    virtual void execute() = 0;};

单例模式Singleton – 学习HeadFirst设计模式记录

单件模式:确保一个类只有一个实例,并提供一个全局访问点. 1.单例模式实现 #include <windows.h>#include <iostream> class Singleton{public:    static Singleton* GetInstance()  /* 单例全局访问点 */    {        if (NULL == _pUniqueInstance) /* 延迟初始化.若使用立刻创建方式,就不会有多线程问题,但是程序启动后就会占用资源. */   

设计模式(9.1)--迭代器与组合模式

缓存(caching): 当组合结构很复杂,或者遍历的代价太高,那么实现组合节点的缓存就很有帮助. (1) Java Collection Framework 指的是一群类的接口. 其中包括了 ArrayList, Vector , LinkedList , Stack ,和 PriorityQueue. 这些类都实现了java.util.Collection接口. (2) Collection接口中的一些方法: add()  , addAll()  , clear() , contains()

设计模式 3 —— 迭代器和组合模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式 概要 设计模式 3 -- 迭代器和组合模式

设计模式(9)--迭代器与组合模式

(1)散列表(hashtable)         共迭代器获取 hashtable.values().iterator();  因为每一笔数据都是由键值对组成. (2)迭代器是用来遍历集合的. Java5后集合都出了自己的遍历方式 如增加for循环.           遍历 也称 游走... (3)数组:Array 长定固定   集合:ArrayList 可扩展,取数据不需要转型 (4)Java中有自己的迭代器接口.在java.util.Iterator  . (5)集合:collectio