大话设计模式20----迭代器模式

来源:互联网 发布:ubuntu 更新内核 编辑:程序博客网 时间:2024/06/16 12:20

大话设计模式


1 迭代器模式(Iterator)结构图




2 对迭代器模式的一些解释


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

迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。

Iterator迭代器抽象类:
class Iterator{public:virtual Object First() = 0;virtual Object Next() = 0;virtual bool IsDone() = 0;virtual Object CurrentItem() = 0;};

Aggregate聚集抽象类
class Aggregate{public:virtual Iterator *CreateIterator() = 0;//创建迭代器};

ConcreteIterator具体迭代器类:
class ConcreteIterator :public Iterator{private://定义一个具体聚集对象ConcreteAggregate *aggregate;int current = 0;public://初始化时将具体的聚集对象传入ConcreteIterator(ConcreteAggregate *aggregate){this->aggregate = aggregate;}//得到聚集的第一个对象Object First() override{return aggregate[0];}//得到聚集的下一个对象Object Next() override{Object ret = null;current++;if (current < aggregate->Count){ret = aggregate[current];}return ret;}//判断当前是否遍历到结尾,到结尾返回truebool IsDone() override{return current >= aggregate->Count ? true : false;}//返回当前的聚集对象Object CurrentItem() override{return aggregate[current];}};

ConcreteAggregate具体聚集类
class ConcreteAggregate :public Aggregate{private:List<Object> *items = new List<Object>();public:Iterator *CreateIterator() override{return new ConcreteIterator();}int Count(){return items->size();}void setObject(int i, Object obj){items[i] = obj;}Object getObject(int i){return items[i];}};

客户端Client.cpp
int main(){ConcreteAggregate *a = new ConcreteAggregate();a[0] = "A";a[1] = "B";a[2] = "C";a[3] = "D";a[4] = "E";a[5] = "F";Iterator *it = new Iterator(a);Object item = it->First();while (!it->IsDone()){cout << it->CurrentItem << endl;it->Next();}return 0;}

3 C++代码实现

Aggregate.h
#ifndef AGGREGATE_H#define AGGREGATE_H#include <vector>#include <string>#include <iostream>class Iterator;class ConcreteIterator;typedef std::string object;//聚集抽象类class Aggregate{public:virtual Iterator* CreateIterator() = 0;virtual std::vector<object>* GetVector() = 0;};//具体聚集类class ConcreteAggregate :public Aggregate{private:std::vector<object> *items;public:ConcreteAggregate();~ConcreteAggregate();//产生从前往后的迭代器Iterator* CreateIterator();//产生从后往前的迭代器Iterator* CreateIteratorDesc();std::vector<object>* GetVector();int Count();object GetElement(int index);void SetElement(int index, object o);};#endif

Aggregate.cpp
#include "Aggregate.h"#include "Iterator.h"ConcreteAggregate::ConcreteAggregate(){items = new std::vector<object>;}ConcreteAggregate::~ConcreteAggregate(){delete items;}Iterator* ConcreteAggregate::CreateIterator(){Iterator* it = new ConcreteIterator(this);return it;}Iterator* ConcreteAggregate::CreateIteratorDesc(){Iterator* it = new ConcreteIteratorDesc(this);return it;}int ConcreteAggregate::Count(){return items->size();}std::vector<object>* ConcreteAggregate::GetVector(){return items;}object ConcreteAggregate::GetElement(int index){return items->at(index);}void ConcreteAggregate::SetElement(int index, object o){items->at(index) = o;}

Iterator.h
#ifndef ITERATOR_H#define ITERATOR_H#include <vector>#include <iostream>#include "Aggregate.h"typedef std::string object;//迭代器抽象类class Iterator{public:virtual object First() = 0;virtual object Next() = 0;virtual bool IsDone() = 0;virtual object CurrentItem() = 0;};//具体迭代器类,从前往后的迭代器class ConcreteIterator :public Iterator{private:ConcreteAggregate* aggregate;int current;public:ConcreteIterator(Aggregate* aggregate);object First();object Next();bool IsDone();object CurrentItem();};//具体迭代器类,从后往前的迭代器class ConcreteIteratorDesc :public Iterator{private:ConcreteAggregate* aggregate;int current;public:ConcreteIteratorDesc(Aggregate* aggregate);object First();object Next();bool IsDone();object CurrentItem();};#endif

Iterator.cpp
#include "Iterator.h"ConcreteIterator::ConcreteIterator(Aggregate* aggregate){this->aggregate = (ConcreteAggregate*)aggregate;current = 0;}object ConcreteIterator::First(){return aggregate->GetVector()->at(0);}object ConcreteIterator::Next(){current++;if (current<aggregate->GetVector()->size())return aggregate->GetVector()->at(current);}bool ConcreteIterator::IsDone(){return current >= aggregate->GetVector()->size() ? true : false;}object ConcreteIterator::CurrentItem(){return aggregate->GetVector()->at(current);}ConcreteIteratorDesc::ConcreteIteratorDesc(Aggregate* aggregate){this->aggregate = (ConcreteAggregate*)aggregate;current = (((ConcreteAggregate*)aggregate)->GetVector()->size()) - 1;}object ConcreteIteratorDesc::First(){return *(aggregate->GetVector()->end());}object ConcreteIteratorDesc::Next(){current--;if (current >= 0)return aggregate->GetVector()->at(current);}bool ConcreteIteratorDesc::IsDone(){return current<0 ? true : false;}object ConcreteIteratorDesc::CurrentItem(){return aggregate->GetVector()->at(current);}

客户端Client.cpp
#include "Iterator.h"#include "Aggregate.h"#include <iostream>#include <cstdlib>//Client客户端void main(){//公交车,即聚集对象ConcreteAggregate* a = new ConcreteAggregate();//新上来的乘客a->GetVector()->push_back("大鸟");a->GetVector()->push_back("小菜");a->GetVector()->push_back("行李");a->GetVector()->push_back("老外");a->GetVector()->push_back("公交内部人员");a->GetVector()->push_back("小偷");//售票员出场,先看好了上车的是哪些人,即声明了迭代器对象。//下面两种获取迭代器的方法都可以//Iterator* i=new ConcreteIterator(a);//产生从前往后的迭代器Iterator* it1 = a->CreateIterator();//告知每一位乘客买票std::cout << "从前往后的迭代器:" << std::endl << std::endl;while (!it1->IsDone()){std::cout << it1->CurrentItem() << "  请买车票!" << std::endl;it1->Next();}std::cout << std::endl;//产生从后往前的迭代器Iterator* it2 = a->CreateIteratorDesc();//告知每一位乘客买票std::cout << "从后往前的迭代器:" << std::endl << std::endl;while (!it2->IsDone()){std::cout << it2->CurrentItem() << "  请买车票!" << std::endl;it2->Next();}std::cout << std::endl << std::endl;delete a, it1, it2;system("pause");}

运行结果:
从前往后的迭代器:大鸟  请买车票!小菜  请买车票!行李  请买车票!老外  请买车票!公交内部人员  请买车票!小偷  请买车票!从后往前的迭代器:小偷  请买车票!公交内部人员  请买车票!老外  请买车票!行李  请买车票!小菜  请买车票!大鸟  请买车票!请按任意键继续. . .

注意:迭代器模式是普遍存在的。许多高级语言都对其进行了封装,反而给人的感觉就是不太常用

以下内容引自<http://blog.csdn.net/zhengzhb/article/details/7610745>,转载请注明出处!!!


卡奴达摩----迭代器模式



定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。

类型:行为类模式

类图


如果要问java中使用最多的一种模式,答案不是单例模式,也不是工厂模式,更不是策略模式,而是迭代器模式,先来看一段代码吧:
public static void print(Collection coll){Iterator it = coll.iterator();while(it.hasNext()){String str = (String)it.next();System.out.println(str);}}

这个方法的作用是循环打印一个字符串集合,里面就用到了迭代器模式,java语言已经完整地实现了迭代器模式,Iterator翻译成汉语就是迭代器的意思。提到迭代器,首先它是与集合相关的,集合也叫聚集、容器等,我们可以将集合看成是一个可以包容对象的容器,例如List,Set,Map,甚至数组都可以叫做集合,而迭代器的作用就是把容器中的对象一个一个地遍历出来。

迭代器模式的结构
  • 抽象容器:一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
  • 具体容器:就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
  • 抽象迭代器:定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove(),
  • 迭代器实现:实现迭代器接口中定义的方法,完成集合的迭代。
代码实现
interface Iterator {public Object next();public boolean hasNext();}class ConcreteIterator implements Iterator{private List list = new ArrayList();private int cursor =0;public ConcreteIterator(List list){this.list = list;}public boolean hasNext() {if(cursor==list.size()){return false;}return true;}public Object next() {Object obj = null;if(this.hasNext()){obj = this.list.get(cursor++);}return obj;}}interface Aggregate {public void add(Object obj);public void remove(Object obj);public Iterator iterator();}class ConcreteAggregate implements Aggregate {private List list = new ArrayList();public void add(Object obj) {list.add(obj);}public Iterator iterator() {return new ConcreteIterator(list);}public void remove(Object obj) {list.remove(obj);}}public class Client {public static void main(String[] args){Aggregate ag = new ConcreteAggregate();ag.add("小明");ag.add("小红");ag.add("小刚");Iterator it = ag.iterator();while(it.hasNext()){String str = (String)it.next();System.out.println(str);}}}

上面的代码中,Aggregate是容器类接口,大家可以想象一下Collection,List,Set等,Aggregate就是他们的简化版,容器类接口中主要有三个方法:添加对象方法add、删除对象方法remove、取得迭代器方法iterator。Iterator是迭代器接口,主要有两个方法:取得迭代对象方法next,判断是否迭代完成方法hasNext,大家可以对比java.util.List和java.util.Iterator两个接口自行思考。

迭代器模式的优缺点
  • 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  • 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  • 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
  • 迭代器模式的缺点:
  • 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。

迭代器模式的适用场景
迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。

但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。

0 0