//---------------------------15/04/26----------------------------

//Iterator 迭代器模式----对象行为型模式

/*

1:意图:

提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

2:别名:

游标(Cursor)

3:动机:

4:适用性:

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

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

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

5:结构:

Aggregate:<-------------Client----------------->Iterator:

CreateIterator()                                First()

|                                           Next()

|                                           IsDone()

|                                           CurrentItem()

|                                               |

ConcreteAggregate()- - - - - - - - - - - - - ->ConcreteIterator

CreateIterator()   <------------------------------|

{ return new ConcreteIterator(this)}

6:参与者:

1>Iterator:

迭代器定义访问和遍历元素的接口。

2>ConcreteIterator:

1)具体迭代器实现迭代器接口。

2)对该聚合遍历时跟踪当前位置。

3>Aggregate:

聚合定义创建相应迭代器对象的接口。

4>ConcreteAggregate:

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

7:协作:

ConcreteIterator跟踪聚合中的当前对象,并能够计算出代遍历的后继对象。

8:效果:

1>它支持以不同的方式遍历一个聚合:

复杂的聚合可用多种方式进行遍历。比如stl中的正常的迭代器以及反向迭代器。

2>迭代器简化了聚合的接口:

有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口,这样就简化了聚合的接口。

3>在同一个聚合上可以有多个遍历:

每个迭代器保持它自己的遍历状态。因此你可以同时进行多个遍历。

9:实现:

迭代器在实现上有许多变化和选择。

1>谁控制该迭代:

由客户来控制迭代的称为外部迭代器,由迭代器控制迭代称为内部迭代器。外部迭代器比较灵活

内部迭代器实现起来比较简单。所以能实现还是实现为外部迭代器的。

2>谁定义遍历算法:

迭代器来负责遍历算法易于在相同聚合上使用不同的迭代算法,也易于在不同的聚合上重用相同的算法。

但是因为要访问聚合中的私有变量,会破坏聚合的封装性

3>迭代器健壮程度如何:

插入和删除操作不能干扰别的迭代器的遍历。为了速度考虑,stl的迭代器并不都能保证这个条件。

4>附加的迭代器操作:

迭代器起码要有First,Next,IsDone,CurrenItem等操作,当然可以附加一些有用的操作,比如

Previous

5>在c++中使用多态的迭代器:

使用多态的迭代器是要付出代价的,也就是客户必须自己删除迭代器指针,所以可以使用智能指针

也就是代理模式。

6>迭代器可有特权访问:

迭代器可以访问聚合的元素,所以可以声明为友元,为了防止多次声明友元,可以定义一个abstract

的迭代器,然后由只要继承这个类就能行了。

7>用于复合对象的迭代器:

在Composite模式中,那些递归聚合结构上,外部迭代器难以实现,因为该结构中不同对象处于嵌套

聚合的多个不同层次,因此一个外部迭代器为跟踪对象必须存储一条纵贯该composite的路径。

8>空迭代器:

一个空迭代器是一个退化的迭代器,它可以帮助处理边界条件,也就是stl中的end()。

`   10:代码示例:                                                                        */

//Aggregate:定义了一些接口

template<class Item>

class List

{

public:

List(long size= DEFAULT_LIST_CAPACITY);

long Count() const;

Item& Get(long index)
const;

};

//abstract Iterator:定义迭代器的接口

template<class Item>

class Iterator

{

public:

virtual void First() =
;

virtual void Next() =
;

virtual bool IsDone()
;

virtual Item CurrenItem()
const = ;

protected:

Iterator();

};

//ConcreteIterator:

template<class Item>

class ListIterator :
public Iterator<Item>

{

public:

ListIterator(const List<Item>* aList);

virtual void First();

virtual void Next();

virtual bool IsDone()
const;

virtual Item CurrenItem()
const;

private:

const List<Item>* _list;

long _current;

}

//只要把当前的位置设置为0就是第一个

template<class Item>

void ListIterator<Item>::First()

{

_current =
;

}

//下一个就是把位置加一

template<class Item>

void ListIterator<Item>::Next()

{

_current++;

}

//如果完成了,说明当前位置大于等于list中的元素了

template<class Item>

bool ListIterator<Item>::IsDone()
const

{

return _current >= _list->Count();

}

//只要当前的位置小于元素数量,就返回当前元素。

template<class Item>

Item ListIterator<Item>::CurrenItem()
const

{

if(IsDone())

throw IteratorOutofBounds;

return _list->Get(_current);

}

//这是一个客户自定义打印函数

void PrintEmployees(Iterator<Employee*>& i)

{

for(i.First(); !i.IsDone(); i.Next())

i.CurrenItem()->Print();

}

//定义一个指向指针list

List<Employee*>* employee;

//...

//定义迭代器

ListIterator<Employee*> forward(employee);

ReverseListIterator<Employee*> backward(employee);

PrintEmployees(forward);

PrintEmployees(backward);

//这是一个不同的list,但是客户需要记住不同的迭代器,会很麻烦,所以我们需要在list

//中实现一个工厂方法,它能直接返回一个abstract类型的迭代器。

SkipList<Employee*>* employees;

//...

SkipListIterator<Employee*> Iterator(employees);

PrintEmployees(iterator);

//抽象的list

template<class Item>

class AbstractList

{

public:

virtual Iterator<Item>* CreateIterator()
const = ;

};

template<class Item>

Iterator<Item>* List<Item>::CreateIterator()
const

{

return new ListIterator<Item>(this);

}

//这样可以不使用具体迭代器类型,直接使用list对象的create函数来创造一个迭代器。

AbstractList<Employee*>* employee;

Iterator<Employee*>* iterator = employee->CreateIterator();

PrintEmployees(*iterator);

delete iterator;

//为了保证迭代器被删除,可以使用智能指针

template<class Item>

class IteratorPtr

{

public:

IteratorPtr(Iterator<Item>* i): _i(i){}

_IteratorPtr(){delete _i};

//每个智能指针都要实现的两个重载

Iterator<Item>*
operator->() { return _i;}

Iterator<Item>*
operator*() { return *_i;}

private:

IteratorPtr(const IteratorPtr&);

IteratorPtr&
operator=(const IteratorPtr&);

private:

Iterator<Item>* _i;

};

//这样就不需要delete了。

AbstractList<Employee*>* employee;

IteratorPtr<Employee*>* iterator = employee->CreateIterator();

PrintEmployees(*iterator);

//一个内部的ListIterator:
遍历操作在内部实现

template<class Item>

class ListTraverser

{

public:

ListTraverser(List<Item>* aList);

bool Traverse();

protected:

virtual bool ProcessItem(const Item&) =
;

private:

ListIterator<Item> _iterator;

};

template<class Item>

ListTraverser<Item>::ListTraverser(List<Item>* aList)

:_iterator(aList){}

//遍历操作

template<class Item>

bool ListTraverser<Item>::Traverse()

{

bool result = false;

for(_iterator.First(); !_iterator.IsDone(); _iterator.Next())

{

result = ProcessItem(_iterator.CurrenItem());

if(result == false)

break;

}

return result;

}

//如果需要打印不同的链表,必须实现不同的迭代器,所以内部迭代器实现会比较麻烦。

class PrintNEmployees :
public ListTraverser<Employee*>

{

public:

PrintNEmployees(List<Employee*>* aList,
int n)

:   ListTraverser<Employee*>(aList), _total(n), _count(){}

protected:

bool ProcessItem(Employee*
const&);

private:

int _total;

int _count;

}

bool PrintNEmployees::ProcessItem(Employee*
const& e)

{

_count++;

e->Print();

return _count < _total;

}

//这里就不需要自己实现遍历函数,直接调用内部迭代器的函数打印。

List<Employee*>* employees;

PrintNEmployees pa(employees,
);

pa.Traverse();

ListIterator<Employee*> i(employees);

//下面是外部迭代器的打印过程,必须自己实现逻辑

int count =
;

for(i.First(); !i.IsDone(); i.Next())

{

count++;

i.CurrenItem()->Print();

)

{

break;

}

}

//这个迭代器可以过滤一些元素,只有通过测试菜能打印出来

template<class Item>

class FilteringListTraverser

{

public:

FilteringListTraverser(List<Item>* aList);

bool Traverse();

protected:

virtual bool ProcessItem(const Item&) =
;

virtual bool TestItem(const Item&) =
;

private:

ListIterator<Item> _iterator;

};

template<class Item>

void FilteringListTraverser<Item>::Traverse()

{

bool result = false;

for(_iterator.First(); !=_iterator.IsDone(); _iterator.Next())

{

//先测试

if(TestItem(_iterator.CurrenItem()))

{

result = ProcessItem(_iterator.CurrenItem());

if(result == false)

break;

}

}

return result;

}

设计模式 笔记 迭代器模式 Iterator的更多相关文章

  1. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

  2. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

    设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...

  3. 二十四种设计模式:迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...

  4. [设计模式] 16 迭代器模式 Iterator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...

  5. 设计模式之迭代器模式(Iterator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. 学习笔记——迭代器模式Iterator

    迭代器模式,使用很多,但是很少实现.常用的集合都支持迭代器. 集合中的CreateIterator()可用于创建自己的迭代器,在里面通过调用迭代器的构造函数Iterator(Aggregate)来绑定 ...

  7. 行为型设计模式之迭代器模式(Iterator)

    结构 意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示. 适用性 访问一个聚合对象的内容而无需暴露它的内部表示. 支持对聚合对象的多种遍历. 为遍历不同的聚合结构提供一 ...

  8. 设计模式之迭代器模式 Iterator

    代码实现 public interface MyIterator { void first(); //将游标指向第一个元素 void next(); //将游标指向下一个元素 boolean hasN ...

  9. 《Head first设计模式》学习笔记 – 迭代器模式

    <Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...

随机推荐

  1. 为何SQL SERVER使用sa账号登录还原数据库BAK文件失败,但是使用windows登录就可以

    今天发现一个问题,就是公司开发服务器上的sql server使用sa账号登录后,还原一个数据库bak文件老是报错,错误如下: TITLE: Microsoft SQL Server Managemen ...

  2. python设计模式之工厂模式

    一.理解工厂模式 在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类.通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法.客户端使用某些参数调用此方法,之后,工厂会据此创建所需类 ...

  3. JAVA 连接 SQL Server 2008:java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver

    新项目需要修改Java开发的MES系统...Java忘的也差不多了...简单尝试以下JAVA连接SQL Server吧,没想到坑还是很多的.以前直接连oracle时没有这么多麻烦啊....可能微软和o ...

  4. 一次SQLServer数据库宕机问题

    数据库采用SQL Server 2005版本, 数据库文件约为6G,而LDF日志文件已经高达36G. 服务器开始变的不太稳定 .数据没有成功保存. 打开事件查看器发现很多信息日志 数据库 '' 中的文 ...

  5. NetworkX 图网络处理工具包

    简单介绍 NetworkX is a Python package for the creation, manipulation, and study of the structure, dynami ...

  6. 启动 uiautomatorviewer 时报 SWT folder '..\lib\location of your Java installation.' does not exist.

    现象,之前本机上的 uiautomatorviewer 一直是好的,最近这段时间无故就不行了,报如标题错误,网上找了各种办法仍无法有效解决,静心细想上一次使用该工具时到目前对本机有做什么跟系统或者工具 ...

  7. saltstack二次开发(一)

    Saltstack简介 Salt是一个配置管理系统,能够维护预定义状态的远程节点(比如,确保指定的包被安装,指定的服务在运行),一个分布式远程执行系统,用来在远程节点(可以是单个节点,也可以是任意规则 ...

  8. SAP客户端 测试机、开发机、生产机

     SAP客户端 测试机.开发机.生产机     客户端(即Client),是SAP组织架构里最高层的组织单元,所有数据,包括静态数据(科目.客户.供应商.物料.资产等).业务数据(采购订单.销售订单. ...

  9. Shallwe学长的模拟赛

    NOIP Simulated Test 这个名字一听就很高端. T1:sGCD:http://uoj.ac/problem/48 题意概述:给定一个长度为$n$的序列,求$sgcd(a_1,a_i)$ ...

  10. 【转】Android Service创建USB HOST通信

    之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...