• 设计模式之迭代器模式(Iterator)


    迭代器在STL运用广泛,类似容器的迭代已经成为其重要特性,而迭代器模式则是利用迭代器概念进行的抽象运用,迭代器模式运用广泛和有用,因为其能够不考虑数据的存储方式,而是直接面对数据进行迭代,也就是说我们不用考虑集合是数组(或vector)、链表、栈还是队列,而是通过统一的接口进行顺序的访问。

    作用

    迭代器模式提供了一种顺序访问容器中元素的方法,而无需了解器内部的类型和结构,该模式的核心思想将访问和遍历容器对象的功能交给一个外部的迭代器对象,该迭代器定义了访问聚合对象的接口,

    类视图

    实现

    class Item
    {
    public:
    	Item(string strName,float price):
    	m_name(strName),m_price(price){}
    	Item(Item& item):
    	m_name(item.strName),m_price(item.price){}
            string tostring()
    	{
    		std::ostringstream buffer;
    		buffer << f;
    		string strPrice =  buffer.str();
    		strName += " :";
                    return strName + strPrice;
    	}
    private:
    	string m_name;
    	float m_price;
    }
    
    class Container;
    class Menu;
    
    class Iterator
    {
    public:
    	virtual ~Iterator(){}
    	virtual void first()=0;
    	virtual void next()=0;
    	virtual bool hasnext()=0;
    	virtual Item* current()=0;
    protected:
    	Container * m_pContainer;
    }
    
    
    class Container 
    {
    public:
        virtual ~Container() {};
        virtual void CreateIterator()= 0; 
    protected:
        Observer(){};
    };
    
    class MenuIterator : public Iterator
    { 
        Menu * m_menu; 
        int curpos; 
    public: 
        MenuIterator(Menu*a):m_menu(a),curpos(0){} 
        virtual void first() 
        { 
            curpos=0;  
        } 
        virtual void next() 
        { 
            curpos++;  
        } 
        virtual bool hasnext() 
        { 
            if(curpos >=0 && curpos< m_menu->size())  
        } 
        virtual Item* current() 
        {
            return m_menu->value(curpos);  
        }
    }; 
    
    
    class Menu : public Container
    {
    public:
    	virtual ~Menu() 
    	{
    		for(int i=0 ; i< m_items.size(); i++)
    		{
    			delete m_items[i];
    		}
    	};
    	Iterator* CreateIterator() 
    	{
    		return new MenuIterator(this); 
    	}
            int size()
    	{
    		return m_items.size();
    	}
    	Item* value(int nIndex)
    	{
    		if(nIndex>=0 && nIndex<m_items.size())
    		{
    			return m_items[nIndex];
    		}
    		else
    		{
    			return NULL;
    		}
    	}
    	void additem(Item& item)
    	{
    		Item *pItem = new Item(item);
    		m_items.push_back(pItem);
    	}
        	
    private: 
        vector<item* > m_items; 
    };
    
    
    int main()
    {
    	Item it1("chicken", 10.0);
            Item it2("Apple", 5.0);
            Item it3("Beaf", 20.0);
            Item it4("soup",15.0);
            
            Menu menu;
    	menu.additem(it1);
    	menu.additem(it2);
    	menu.additem(it3);
    	menu.additem(it4);
    	
            Iterator itor = menu.CreateIterator();
    	while(itor->hasnext())
    	{
    		Item* pItem = itor->current();
    		if(pItem)
    			cout<<pItem->tostring()<<endl;
    		itor->next();
    	}
    }
    
    

    对于上例来说,Iterator接口是不变的,不管menu中的聚合内容的形式如何变化,只要menu根据其类型提供其取值、大小等的操作,那么对于使用者来说都是一样的操作。

    应用场景

    1. 访问一个聚合对象的内容而无需暴露它的内部表示;
    2. 支持对聚合对象的多种遍历(从前到后,从后到前);
    3. 为遍历不同的聚合结构提供一个统一的接口,支持多态迭代。
  • 相关阅读:
    软件推荐Q10 CircleDock PHP
    Google Chrome浏览器 扩展程序推荐 PHP
    jsColor取色器 PHP
    在线指法练习【怀旧版】 PHP
    model工厂类(转)
    表变量与临时表的优缺点
    项目的阶段性目标管理
    如何配置不启用安全的WCF服务
    团队高效执行力从何而来
    socket connect函数本质含义
  • 原文地址:https://www.cnblogs.com/chencarl/p/8729670.html
Copyright © 2020-2023  润新知