zoukankan      html  css  js  c++  java
  • 设计模式之迭代器模式(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. 为遍历不同的聚合结构提供一个统一的接口,支持多态迭代。
  • 相关阅读:
    求大神回答这个管理系统不知道为啥不成功急!
    这个函数到底什么意思如何调用
    判断浮点数是否为零的问题
    字符串与列表的 常用方法
    变量名命名规范 运算符 流程控制
    ACM C++
    struts s:iterator循环遍历数据 自动生成序号
    JAVA将一个EXCEL多行订单产品字符串分解成一个个子订单 +连接符连接
    JS在HTML中获取到所有选中的checkbox的值
    自己做的java-WEB项目。希望360浏览器能够默认使用极速模式打开
  • 原文地址:https://www.cnblogs.com/chencarl/p/8729670.html
Copyright © 2011-2022 走看看