【设计模式学习笔记十七】【行为模式】【迭代器模式(Interpreter)】

本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.csdn.net/lovelion/article/details/17517213

主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.迭代器模式

迭代器是很常见的模式,他将聚合类中负责遍历数据的方法提取出来,封装到专门的类中,实现数据存储和数据遍历的分离,无需暴露聚合类的内部类属性即可对其进行操作。我们常用聚合对象来存储一系列的数据,如vector,聚合对象拥有两个职责:一是存储数据,而是遍历数据。前者是聚合对象的基本职责,后者是可变化和分离的。将遍历数据的行为从聚合对象中分离出来,封装在一个被称为迭代器的对象中,由迭代器来提供遍历聚合类对象内部数据的行为。

(1)定义

迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部元素。

1)迭代器结构图

在迭代器结构图中包含聚合和迭代器两个层次结构,考虑到系统的灵活性和可扩展性,在迭代器中应用了工厂方法模式。

2)参与者

a) Iterator(抽象迭代器):定义访问和遍历元素的借口;

b) ConcreteIterator(具体迭代器):具体迭代器实现迭代器的接口,对该聚合遍历时跟踪当前位置;

c) Aggregate(聚合):存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂的角色。

d) ConcreteAggregate(具体聚合类):创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。

3)看图写代码

/*
 ** FileName     : IteratorPattern
 ** Author       : lin005
 ** Date         : 2015/02/08
 ** Description  : More information, please go to http://blog.csdn.net/amd123456789
 */
//define a node
typedef struct Node_s
{
    int value;
    Node_s* next;
}Node;
class p_List; //提前申明

//Abstract Iterator
class _Iterator
{
public:
    virtual ~_Iterator(){};
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual bool IsLast() = 0;
    virtual Node* getCurrentNode() = 0;
};
//抽象迭代器的子类
class ConcreteIterator : public _Iterator
{
public:
    ConcreteIterator(p_List* l):list(l){}
    ~ConcreteIterator();
    virtual void First();  //第一个元素
    virtual void Next();   //当前元素的下一个元素
    virtual bool IsLast(); //是否最后一个元素
    virtual Node* getCurrentNode(); //获取当前迭代器所指向的元素
private:
    p_List* list;  //包含链表
    Node* pc;      //当前元素
};
//链表
class p_List
{
public:
    p_List(){phead = NULL; ptail = NULL; count = 0;}
    ~p_List()
    {
        removeAll();
        if(iter)
        {
            delete iter;
            iter = NULL;
        }
    }
    //获取元素个数
    int getCount()
    {
        return count;
    }
    //获取指定元素
    Node* get(const int a)const
    {
        Node* p = phead;
        while(p)
        {
            if(p->value == a)
            {
                return p;
            }
            p = p->next;
        }
        return NULL;
    }
    //获取第一个元素
    Node* First()const
    {
        return phead;
    }
    //获取最后一个元素
    Node* Last()const
    {
        return ptail;
    }
    //是否包含指定元素
    bool IsInclude(const int a)const
    {
        Node* p = phead;
        while(p)
        {
            if(p->value == a)
            {
                return true;
            }
            p = p->next;
        }
        return false;
    }
    //添加一个指定元素
    void add(const int a)
    {
        Node *pnew = new Node;
        pnew->next = NULL;
        pnew->value = a;
        if(phead == NULL)
        {
            phead = pnew;
            ptail = pnew;
            count++;
        }
        else
        {
            ptail->next = pnew;
            ptail = pnew;
        }
    }
    //删除一个元素
    void remove(Node* p)
    {
        if(phead == NULL)
            return;
        if(phead == p)
        {
            if(phead->next == NULL)
            {
                ptail = NULL;
            }
            phead = p->next;
            delete p;
            p = NULL;
        }
        else
        {
            Node* pt = phead;
            while(pt)
            {
                if(pt->next == p)
                {
                    //if(p->next == NULL)
                    {
                        //   pt->next = NULL;
                    }
                    // else
                    {
                        pt->next = pt->next->next;
                    }
                    delete p;
                    p = NULL;
                    break;
                }
                pt = pt->next;
            }
        }
    }
    //删除所有元素
    void removeAll()
    {
        while(phead)
        {
            Node* p = phead;
            phead = p->next;
            delete p;
            p = NULL;
        }
        ptail = NULL;
    }
    //是否第一个元素
    bool isFirst(Node* p)
    {
        if(p == phead)
            return true;
        return false;
    }
    //链表是否为空
    bool isEmpty()
    {
        return count == 0;
    }
    //生成一个迭代器
    _Iterator* createdIter()
    {
        iter = new ConcreteIterator(this);
        return iter;
    }
private:
    Node* phead; //第一个节点
    Node* ptail; //最后一个节点
    int count;   //元素个数
    _Iterator* iter; //迭代器
};

void ConcreteIterator::First()
{
    pc = list->First();
}
void ConcreteIterator::Next()
{
    if(list->First())
    {
        pc = pc->next;
    }
    else
    {
        pc = NULL;
    }
}
bool ConcreteIterator::IsLast()
{
    return pc == list->Last()->next;
}
Node* ConcreteIterator::getCurrentNode()
{
    return pc;
}
ConcreteIterator::~ConcreteIterator()
{
}
//客户端测试
#define SAFE_DELETE(p) if(p){delete p; p = NULL;}
int main(int argc, const char * argv[]) {

    p_List* l = new p_List();
    l->add(20);
    l->add(30);
    l->add(40);
    _Iterator* iter = new ConcreteIterator(l);//有客户端主动生成迭代器,需要手动delete
    _Iterator* iter1 = l->createdIter(); //直接用链表自己生成
    //客户端生成迭代器测试
    for(iter->First(); !iter->IsLast();iter->Next())
    {
        cout<<iter->getCurrentNode()->value<<endl;
    }
    //链表生成的迭代器
    for(iter1->First(); !iter1->IsLast(); iter1->Next())
    {
        if(iter1->getCurrentNode()->value == 20)
        {
            l->remove(iter1->getCurrentNode());
        }
    }
    //链表生成迭代器测试
    for(iter1->First(); !iter1->IsLast();iter1->Next())
    {
        cout<<iter1->getCurrentNode()->value<<endl;
    }
    SAFE_DELETE(l);
    SAFE_DELETE(iter);
    return 0;
}

(2)总结

1)优点

a) 支持不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。仅需用一个不同的迭代器的实例替代原先的实例即可

b) 迭代器简化了聚合类的接口。

c) 在同一个聚合器上可以有多个遍历。每个迭代器保持他自己的遍历状态,因此可以同时进行多个遍历。

d) 在迭代器中引入抽象层,增加新的聚合类和迭代器很方便,无需修改原有代码,符合开闭原则。

2)缺点

a) 迭代器分离了数据存储和遍历数据的职责,增加新的聚合类需要增加对应的迭代器类,类的个数成对增加,一定程度上增加的系统的复杂性。

b) 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。

(3)适用场景

1) 访问一个聚合对象而无需暴露它的内部表示。

2) 支持对聚合对象的多种遍历。

3) 为遍历不同的聚合结构提供一个统一的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值