Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39279
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-17 11:05
文章分类
文章存档

2015年(28)

我的朋友

分类: Java

2015-04-20 19:09:23


迭代器模式的介绍

迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去承担不同的职责。迭代器模式就是用迭代器类来承担遍历集合元素的职责。

迭代器模式的定义

迭代器模式提供了一种方法顺序访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

迭代器模式的结构

既然,迭代器模式承担了遍历集合对象的职责,则该模式自然存在2个类,一个是聚合类,一个是迭代器类。在面向对象涉及原则中还有一条是针对接口编程,所以,在迭代器模式中,抽象了2个接口,一个是聚合接口,另一个是迭代器接口,这样迭代器模式中就四个角色了,具体的类图如下所示:



从上图可以看出,迭代器模式由以下角色组成:

  • 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口
  • 具体迭代器角色(Concrete Iteraror):具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置。
  • 聚合角色(Aggregate):聚合角色负责定义获得迭代器角色的接口
  • 具体聚合角色(Concrete Aggregate):具体聚合角色实现聚合角色接口。

迭代器模式的实现

介绍完迭代器模式之后,下面就具体看看迭代器模式的实现,具体实现代码如下:


点击(此处)折叠或打开

  1. // 抽象聚合类
  2.     public interface IListCollection
  3.     {
  4.         Iterator GetIterator();
  5.     }
  6.  
  7.     // 迭代器抽象类
  8.     public interface Iterator
  9.     {
  10.         bool MoveNext();
  11.         Object GetCurrent();
  12.         void Next();
  13.         void Reset();
  14.     }
  15.  
  16.     // 具体聚合类
  17.     public class ConcreteList : IListCollection
  18.     {
  19.         int[] collection;
  20.         public ConcreteList()
  21.         {
  22.             collection = new int[] { 2, 4, 6, 8 };
  23.         }
  24.  
  25.         public Iterator GetIterator()
  26.         {
  27.             return new ConcreteIterator(this);
  28.         }
  29.  
  30.         public int Length
  31.         {
  32.             get { return collection.Length; }
  33.         }
  34.  
  35.         public int GetElement(int index)
  36.         {
  37.             return collection[index];
  38.         }
  39.     }
  40.  
  41.     // 具体迭代器类
  42.     public class ConcreteIterator : Iterator
  43.     {
  44.         // 迭代器要集合对象进行遍历操作,自然就需要引用集合对象
  45.         private ConcreteList _list;
  46.         private int _index;
  47.  
  48.         public ConcreteIterator(ConcreteList list)
  49.         {
  50.             _list = list;
  51.             _index = 0;
  52.         }
  53.  
  54.         public bool MoveNext()
  55.         {
  56.             if (_index < _list.Length)
  57.             {
  58.                 return true;
  59.             }
  60.             return false;
  61.         }
  62.  
  63.         public Object GetCurrent()
  64.         {
  65.             return _list.GetElement(_index);
  66.         }
  67.  
  68.         public void Reset()
  69.         {
  70.             _index = 0;
  71.         }
  72.  
  73.         public void Next()
  74.         {
  75.             if (_index < _list.Length)
  76.             {
  77.                 _index++;
  78.             }
  79.  
  80.         }
  81.     }
  82.  
  83.     // 客户端
  84.     class Program
  85.     {
  86.         static void Main(string[] args)
  87.         {
  88.             Iterator iterator;
  89.             IListCollection list = new ConcreteList();
  90.             iterator = list.GetIterator();
  91.  
  92.             while (iterator.MoveNext())
  93.             {
  94.                 int i = (int)iterator.GetCurrent();
  95.                 Console.WriteLine(i.ToString());
  96.                 iterator.Next();
  97.             }
  98.  
  99.             Console.Read();
  100.         }
  101.     }

迭代器模式的适用场景

在下面的情况下可以考虑使用迭代器模式:

  • 系统需要访问一个聚合对象的内容而无需暴露它的内部表示。
  • 系统需要支持对聚合对象的多种遍历。
  • 系统需要为不同的聚合结构提供一个统一的接口。

迭代器模式的优缺点

由于迭代器承担了遍历集合的职责,从而有以下的优点:

  • 迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象。
  • 迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作

迭代器模式存在的缺陷:

  • 迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。

总结

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


阅读(437) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~