Chinaunix首页 | 论坛 | 博客
  • 博客访问: 628682
  • 博文数量: 87
  • 博客积分: 3399
  • 博客等级: 中校
  • 技术积分: 1422
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 21:20
文章分类

全部博文(87)

文章存档

2013年(1)

2012年(51)

2011年(33)

2010年(2)

分类: 项目管理

2011-08-05 18:59:00

迭代器模式 Iterator
 
结构:
意图:

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

适用性:

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

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

3)为遍历不同的聚合结构提供统一的接口,即支持多态迭代。

举例: 1C++标准模板库是迭代器模式一个极为成功的应用。
 
示例:
  1. // Iterator


  2. // Intent: "Provide a way to access the elements of an aggregate object

  3. // sequentially without exposing its underlying representation".

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


  5. // For further information, read "Design Patterns", p257, Gamma et al.,

  6. // Addison-Wesley, ISBN:0-201-63361-2


  7. /* Notes:
  8.  * Here wish wish to separate node traversal from the nodes themselves.
  9.  * STL in ISO C++ is a highly successful application of this pattern.
  10.  * Generic programming is a great way to implement iterators. As this is
  11.  * not yet in C#, we use inheritance.
  12.  * 将节点和对节点的遍历相分离。
  13.  * C++标准模板库是这种模式的一个很成功的应用。泛型编程是迭代器实现模式模式的上佳方式
  14.  */

  15. namespace Iterator_DesignPattern
  16. {
  17.     using System;
  18.     using System.Collections;

  19.     class Node //elements in aggregate

  20.     {
  21.         private string name;
  22.         public string Name
  23.         {
  24.             get
  25.             {
  26.                 return name;
  27.             }
  28.         }
  29.         public Node(string s)
  30.         {
  31.             name = s;
  32.         }
  33.     }

  34.     class NodeCollection //aggregate

  35.     {
  36.         private ArrayList list = new ArrayList();
  37.         private int nodeMax = 0;

  38.         // left as a student exercise - implement collection

  39.         // functions to remove and edit entries also

  40.         public void AddNode(Node n)
  41.         {
  42.             list.Add(n);
  43.             nodeMax++;
  44.         }
  45.         public Node GetNode(int i)
  46.         {
  47.             return ((Node)list[i]);
  48.         }

  49.         public int NodeMax
  50.         {
  51.             get
  52.             {
  53.                 return nodeMax;
  54.             }
  55.         }
  56.     }

  57.     /*
  58.      * The iterator needs to understand how to traverse the collection
  59.      * It can do that as way it pleases - forward, reverse, depth-first,
  60.      */
  61.     abstract class Iterator //abstract Iterator

  62.     {
  63.         abstract public Node Next();
  64.     }

  65.     class ReverseIterator : Iterator //concrete Iterator

  66.     {
  67.         private NodeCollection nodeCollection;
  68.         private int currentIndex;

  69.         public ReverseIterator(NodeCollection c)
  70.         {
  71.             nodeCollection = c;
  72.             currentIndex = c.NodeMax - 1; // array index starts at 0!

  73.         }

  74.         // note: as the code stands, if the collection changes,

  75.         // the iterator needs to be restarted

  76.         override public Node Next()
  77.         {
  78.             if (currentIndex == -1)
  79.                 return null;
  80.             else
  81.                 return (nodeCollection.GetNode(currentIndex--));
  82.         }
  83.     }

  84.     ///

  85.     /// Summary description for Client.

  86.     ///

  87.     public class Client
  88.     {
  89.         public static int Main(string[] args)
  90.         {
  91.             NodeCollection c = new NodeCollection();
  92.             c.AddNode(new Node("first"));
  93.             c.AddNode(new Node("second"));
  94.             c.AddNode(new Node("third"));

  95.             // now use iterator to traverse this

  96.             ReverseIterator i = new ReverseIterator(c);

  97.             // the code below will work with any iterator type

  98.             Node n;
  99.             do
  100.             {
  101.                 n = i.Next();
  102.                 if (n != null)
  103.                     Console.WriteLine("{0}", n.Name);
  104.             } while (n != null);

  105.             Console.Read();
  106.             return 0;
  107.         }
  108.     }
  109. }

如下是《大话设计模式》中的一个例子,稍作改变:

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace IteratorExample
  6. {
  7.     abstract class Aggregate
  8.     {
  9.         public abstract Iterator CreateIterator();
  10.     }
  11.     class ConcreteAggregate:Aggregate
  12.     {
  13.         private IList<object> items = new List<object>();
  14.         public override Iterator CreateIterator()
  15.         {
  16.             return new ConcreteIterator(this);
  17.         }
  18.         public int Count
  19.         {
  20.             get { return items.Count; }
  21.         }
  22.         public object this[int index]
  23.         {
  24.             get { return items[index]; }
  25.             set { items.Insert(index, value); }
  26.         }
  27.     }
  28.     //抽象迭代类

  29.     abstract class Iterator
  30.     {
  31.         public abstract object First();
  32.         public abstract object Next();
  33.         public abstract bool IsDone();
  34.         public abstract object CurrentItem();
  35.     }
  36.     //以顺序方式迭代

  37.     class ConcreteIterator:Iterator
  38.     {
  39.         private ConcreteAggregate aggregate;
  40.         private int current = 0; //从第一个开始顺序迭代

  41.         public ConcreteIterator(ConcreteAggregate aggregate)
  42.         {
  43.             this.aggregate = aggregate;
  44.         }
  45.         public override object First()
  46.         {
  47.       return aggregate[0];
  48.         }
  49.         public override object Next()
  50.         {
  51.              object ret = null;
  52.             current++;
  53.             if(current < aggregate.Count)
  54.             {
  55.                 ret = aggregate[current];
  56.             }
  57.             return ret;
  58.         }
  59.         public override bool IsDone()
  60.         {
  61.             return current >= aggregate.Count ? true:false;
  62.         }
  63.         public override object CurrentItem()
  64.         {
  65.             return aggregate[current];
  66.         }
  67.     }
  68.     //以逆序方式迭代

  69.     class ConcreteIteratorDesc : Iterator
  70.     {
  71.         private ConcreteAggregate aggregate;
  72.         private int current = 0;
  73.         public ConcreteIteratorDesc(ConcreteAggregate aggregate)
  74.         {
  75.             this.aggregate = aggregate;
  76.             current = aggregate.Count - 1;//从最后一个开始逆序迭代

  77.         }
  78.         public override object First()
  79.         {
  80.             return aggregate[aggregate.Count - 1];
  81.         }
  82.         public override object Next()
  83.         {
  84.             object ret = null;
  85.             current--;
  86.             if (current >= 0)
  87.             {
  88.                 ret = aggregate[current];
  89.             }
  90.             return ret;
  91.         }
  92.         public override object CurrentItem()
  93.         {
  94.             return aggregate[current];
  95.         }
  96.         public override bool IsDone()
  97.         {
  98.             return current < 0 ? true : false;
  99.         }
  100.     }
  101.     //------------------------------------------

  102.     class Client
  103.     {
  104.         public static void Main(string[] args)
  105.         {
  106.             ConcreteAggregate a = new ConcreteAggregate();
  107.             a[0] = "zhangsan";
  108.             a[1] = "lisi";
  109.             a[2] = "wanger";

  110.             // iterate asc

  111.             Console.WriteLine("====iterate asc====");
  112.             Iterator i = new ConcreteIterator(a);
  113.             object item = i.First();
  114.             while (!i.IsDone())
  115.             {
  116.                 Console.WriteLine("{0}", i.CurrentItem());
  117.                 i.Next();
  118.             }

  119.             // iterate desc

  120.             Console.WriteLine("====iterate dasc====");
  121.             Iterator it = new ConcreteIteratorDesc(a);
  122.             item = it.First();
  123.             while (!it.IsDone())
  124.             {
  125.                 Console.WriteLine("{0}", it.CurrentItem());
  126.                 it.Next();
  127.             }

  128.             Console.Read();
  129.         }
  130.     }
  131. }
阅读(698) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~