Iterator pattern

From Wikipedia, the free encyclopedia

In object-oriented programming, the Iterator pattern is a design pattern in which iterators are used to access the elements of an aggregate object sequentially without exposing its underlying representation. An Iterator object encapsulates the internal structure of how the iteration occurs.

For example, a tree, linked list, hash table, and an array all need to be iterated with Search, Sort, Next. Rather than having 12 different methods to manage (4 times the previous 3 functions), using this Pattern you would need to manage only 7. (the previous 3 functions, now in the iterator, + 4 times: getting the iterator)

Contents

[edit] Examples

[edit] PHP 5

As a default behavior in PHP 5, using an object in a foreach structure will traverse all public values. Multiple Iterator classes are available with PHP to allow you to iterate through common lists, such as directories, XML structures and recursive arrays.

It's possible to define your own Iterator classes by implementing the Iterator interface, which will override the default behavior.

The Iterator interface definition:

interface Iterator
{
    // Returns the current value
    function current();
 
    // Returns the current key
    function key();
 
    // Moves the internal pointer to the next element
    function next();
 
    // Moves the internal pointer to the first element
    function rewind();
 
    // If the current element is not at all valid (boolean)
    function valid();
}

These methods are all being used in a complete foreach( $object as $key=>$value ) sequence. The methods are executed in the following order:

rewind() 
if valid() {
    current() in $value 
    key() in $key 
    next()
} 
End of Loop

According to Zend, the current() method is called before and after the valid() method

It is also called as : Cursor pattern.

[edit] C++

The following C++ program gives the implementation of iterator design pattern with generic C++ template:

Console output:

________________Iterator with int______________________________________
0
1
2
3
4
5
6
7
8
9
________________Iterator with Class Money______________________________
100
1000
10000
________________Set Iterator with Class Name___________________________
Amt
Bmt
Cmt
Qmt
/************************************************************************/
/* Iterator.h                                                           */
/************************************************************************/
#ifndef MY_ITERATOR_HEADER
#define MY_ITERATOR_HEADER
 
//////////////////////////////////////////////////////////////////////////
template<class T,class U>
class Iterator
{
public:
        typedef std::vector<T>::iterator iter_type;
        Iterator(U*  pData):m_pData(pData){
                m_it = m_pData->m_data.begin();
        }
 
        void first()
        {
                m_it = m_pData->m_data.begin();
        }
 
        void next()
        {
                m_it++;
        }
 
        bool isDone()
        {
                return (m_it == m_pData->m_data.end());
        }
 
        iter_type current()
        {
                return m_it;
        }
private:
        U* m_pData;
        iter_type m_it;
};
 
template<class T,class U,class A>
class setIterator
{
public:
        typedef std::set<T,U>::iterator iter_type;
 
        setIterator(A* pData):m_pData(pData)
        {
                m_it = m_pData->m_data.begin();
        }
 
        void first()
        {
                m_it = m_pData->m_data.begin();
        }
 
        void next()
        {
                m_it++;
        }
 
        bool isDone()
        {
                return (m_it == m_pData->m_data.end());
        }
 
        iter_type current()
        {
                return m_it;
        }
 
private:
        A*                              m_pData;                
        iter_type               m_it;
};
#endif
/************************************************************************/
/* Aggregate.h                                                           */
/************************************************************************/
#ifndef MY_DATACOLLECTION_HEADER
#define MY_DATACOLLECTION_HEADER
 
#include "MyIterator.h"
 
template <class T>
class aggregate
{
        friend Iterator<T,aggregate>;
public:
        void add(T a)
        {
                m_data.push_back(a);
        }
 
        Iterator<T,aggregate>* create_iterator()
        {
                return new Iterator<T,aggregate>(this);
        }
 
 
private:
        std::vector<T> m_data;
};
template <class T,class U>
class aggregateSet
{
        friend setIterator<T,U,aggregateSet>;
public:
        void add(T a)
        {
                m_data.insert(a);
        }
 
        setIterator<T,U,aggregateSet>* create_iterator()
        {
                return new setIterator<T,U,aggregateSet>(this);
        }
 
        void Print()
        {
                copy(m_data.begin(),m_data.end(),ostream_iterator<T>(cout,"\r\n"));
        }
 
protected:
private:
        std::set<T,U> m_data;
};
 
#endif
/************************************************************************/
/* Iterator Test.cpp                                                     */
/************************************************************************/
#include <iostream>
#include <vector>
using namespace std;
 
class Money
{
public:
        Money(int a=0):m_data(a){}
 
        void SetMoney(int a){
                m_data = a;
        }
 
        int GetMoney()
        {
                return m_data;
        }
 
protected:
private:
        int m_data;
};
 
class Name
{
public:
        Name(string name):m_name(name){}
 
        const string& GetName() const{
                return m_name;
        }
 
        friend ostream operator<<(ostream cout,Name name)
        {
                cout<<name.GetName();
                return cout;
        }
 
private:
        string m_name;
};
 
struct NameLess
{
        bool operator() ( const Name& lhs, const Name& rhs) const
        {
                return lhs.GetName() < rhs.GetName();
        }
};
 
void main( void ) {
                //sample 1
        cout<<"________________Iterator with int______________________________________"<<endl;
        aggregate<int> agg;
 
        for(int i=0;i<10;i++)
        {
                agg.add(i);
        }
 
 
        Iterator< int,aggregate<int> > *it = agg.create_iterator();
        for(it->first();!it->isDone();it->next())
        {
                cout<<*it->current()<<endl;
        }
 
 
        //sample 2
        aggregate<Money> agg2;
        Money a(100),b(1000),c(10000);
        agg2.add(a);
        agg2.add(b);
        agg2.add(c);
 
        cout<<"________________Iterator with Class Money______________________________"<<endl;
        Iterator< Money,aggregate<Money> > *it2 = agg2.create_iterator();
        it2->first();
        while (!it2->isDone()) {
                cout<<((Money*)(it2->current()))->GetMoney()<<endl;
                it2->next();
        }
 
        //sample 3
        cout<<"________________Set Iterator with Class Name______________________________"<<endl;
 
        aggregateSet<Name,NameLess> aset;
        aset.add(Name("Qmt"));
        aset.add(Name("Bmt"));
        aset.add(Name("Cmt"));
        aset.add(Name("Amt"));
 
 
        setIterator<Name,NameLess,aggregateSet<Name,NameLess>  > * it3 = aset.create_iterator();
        for(it3->first();!it3->isDone();it3->next())
        {
                cout<<(*it3->current())<<endl;
        }
}

[edit] See also

[edit] External links

  • Jt J2EE Pattern Oriented Framework