**20.迭代器模式(Iterator)

意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
上下文:集合对象内部结构常常变化各异。对于这些集合对象,能否在不暴露其内部结构的同时,让外部Client透明地访问其中包含的元素,同时让这种"透明遍历"也为"同一种算法在多种集合对象上进行操作"提供可能?

UML

Iterator:定义访问和遍历元素的接口(.NET中定义了标准的IEnumrator接口)。ConcreteIterator:实现Iterator接口,同时在对Aggregate遍历时跟踪当前的位置。Aggregate:定义创建相应Iterator对象的接口(.NET中定义了标准的IEnumrable接口)。ConcreteAggregate:实现创建相应Iterator对象的接口,该操作返回一个适当的ConcreteIterator实例。
注意:.NET中的foreach关键字在编译时会自动创建迭代器对象,并使用该对象对集合进行遍历。.NET中的yield return关键字使得定义迭代器对象更加容易。

代码

cpp 复制代码
#include <iostream>
#include <list>
#include <array>
#include <vector>
using namespace std;
 
//Iterator迭代器抽象类
class Iterator
{
public:
    virtual void* First() = 0;
    virtual void* Next() = 0;
    virtual bool IsDone() = 0;
    virtual void* CurrentItem() = 0;
};
 
//Aggregate聚集抽象类
class Aggregate
{
public:
    virtual Iterator *CreateIterator() = 0;
};
 
//ConcreteAggregate具体聚集类 继承Aggregate
class ConcreteAggregate:public Aggregate
{
public:
    vector<void*> items;
    // Aggregate interface
public:
    Iterator *CreateIterator();
    int getCount() const;
    //既可以作为左值,也可以作为又值
    void** operator[](unsigned int index){
        if(items.size() <= index){
            items.resize(index+1);
        }
        return &items[index];
    }
};
 
class ConcreteIterator:public Iterator
{
public:
    ConcreteAggregate *ca;
    int current;
    ConcreteIterator(ConcreteAggregate *c):ca(c){
        this->current = 0;
    }
    virtual void* First();
    virtual void* Next();
    virtual bool IsDone();
    virtual void* CurrentItem();
};
 
Iterator *ConcreteAggregate::CreateIterator()
{
    return new ConcreteIterator(this);
}
 
int ConcreteAggregate::getCount() const
{
    return items.size();
}
 
void *ConcreteIterator::First()
{
    return *(*ca)[0];
}
 
void *ConcreteIterator::Next()
{
    if(current < ca->getCount()){
        current++;
    }
    if(current < ca->getCount()){
        return *(*ca)[current];
    }
    return nullptr;
}
 
bool ConcreteIterator::IsDone()
{
    return current >= ca->getCount()?true:false;
}
 
void *ConcreteIterator::CurrentItem()
{
    return *(*ca)[current];
}
 
class ConcreteIteratorDesc:public Iterator
{
public:
    ConcreteAggregate *ca;
    int current;
    ConcreteIteratorDesc(ConcreteAggregate *c):ca(c){
        this->current = c->getCount() - 1;
    }
    virtual void* First();
    virtual void* Next();
    virtual bool IsDone();
    virtual void* CurrentItem();
};
void *ConcreteIteratorDesc::First()
{
    if(ca->getCount() == 0){
        return nullptr;
    }
    return *(*ca)[ca->getCount() - 1];
}
 
void *ConcreteIteratorDesc::Next()
{
    if(current >= 0){
        current--;
    }
    if(current >= 0){
        return *(*ca)[current];
    }
    return nullptr;
}
 
bool ConcreteIteratorDesc::IsDone()
{
    return current < 0?true:false;
}
void *ConcreteIteratorDesc::CurrentItem()
{
    return *(*ca)[current];
}
int main()
{
    ConcreteAggregate ca;
    *(ca[0]) = (void*)5;
    *ca[1] = (void*)10;
    *ca[2] = (void*)15;
    *ca[3] = (void*)20;
//    cout << (int) *ca[0] << endl;
//    cout << (int) *ca[1] << endl;
//    cout << ca.getCount() << endl;
 
    Iterator *i = new ConcreteIterator(&ca);
 
    cout << "开始遍历" << endl;
    while(!i->IsDone()){
        cout << (int)i->CurrentItem() << endl;
        i->Next();
    }
 
    Iterator *i_desc = new ConcreteIteratorDesc(&ca);
 
    cout << "开始反向遍历" << endl;
    while(!i_desc->IsDone()){
        cout << (int)i_desc->CurrentItem() << endl;
        i_desc->Next();
    }
    cout << "--end--" << endl;
    return 0;
}

结果:

开始遍历
5
10
15
20
开始反向遍历
20
15
10
5
--end--
相关推荐
程序员与背包客_CoderZ8 天前
C++设计模式——Iterator迭代器模式
linux·c语言·开发语言·c++·设计模式·迭代器模式
AI让世界更懂你12 天前
漫谈设计模式 [14]:迭代器模式
python·设计模式·迭代器模式
LB_bei13 天前
设计模式-行为型模式-迭代器模式
设计模式·迭代器模式
惜.己17 天前
设计模式之迭代器模式
java·设计模式·迭代器模式·intellij-idea
WineMonk17 天前
设计模式 16 迭代器模式
设计模式·迭代器模式
屋外雨大,惊蛰出没22 天前
迭代器模式
迭代器模式·二十三种设计模式(java)
Fuliy9625 天前
游戏开发设计模式之迭代器模式
java·开发语言·算法·unity·设计模式·迭代器模式
谢尔登1 个月前
【设计模式】模板方法模式和迭代器模式
设计模式·迭代器模式·模板方法模式
正在走向自律1 个月前
Java二十三种设计模式-迭代子模式(16/23)
设计模式·迭代器模式·行为型模式
郑同学zxc1 个月前
设计模式22-迭代器模式
设计模式·迭代器模式