设计模式之Iterator迭代模式


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

适用性:

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

DefinitionProvide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Participants

    The classes and/or objects participating in this pattern are:

  • Iterator  (AbstractIterator)
    • defines an interface for accessing and traversing elements.
  • ConcreteIterator  (Iterator)
    • implements the Iterator interface.
    • keeps track of the current position in the traversal of the aggregate.
  • Aggregate  (AbstractCollection)
    • defines an interface for creating an Iterator object
  • ConcreteAggregate  (Collection)
    • implements the Iterator creation interface to return an instance of the proper ConcreteIterator

Iterator迭代模式,提供了一个访问ConcreteAggregate的方法。在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为同一种算法在多种集合对象上进行操作提供了可能。迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。

 

Sample code in c#

This structural code demonstrates the Iterator pattern which provides for a way to traverse (iterate) over a collection of items without detailing the underlying structure of the collection.

// Iterator pattern -- Structural example

 

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Iterator.Structural
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      ConcreteAggregate a = new ConcreteAggregate();
      a[0] = "Item A";
      a[1] = "Item B";
      a[2] = "Item C";
      a[3] = "Item D";

      // Create Iterator and provide aggregate
      ConcreteIterator i = new ConcreteIterator(a);

      Console.WriteLine("Iterating over collection:");
      
      object item = i.First();
      while (item != null)
      {
        Console.WriteLine(item);
        item = i.Next();
      }

      // Wait for user
      Console.Read();
    }
  }

  // "Aggregate"

  abstract class Aggregate
  {
    public abstract Iterator CreateIterator();
  }

  // "ConcreteAggregate"

  class ConcreteAggregate : Aggregate
  {
    private ArrayList items = new ArrayList();

    public override Iterator CreateIterator()
    {
      return new ConcreteIterator(this);
    }

    // Property
    public int Count
    {
      get{ return items.Count; }
    }

    // Indexer
    public object this[int index]
    {
      get{ return items[index]; }
      set{ items.Insert(index, value); }
    }
  }

  // "Iterator"

  abstract class Iterator
  {
    public abstract object First();
    public abstract object Next();
    public abstract bool IsDone();
    public abstract object CurrentItem();
  }

  // "ConcreteIterator"

  class ConcreteIterator : Iterator
  {
    private ConcreteAggregate aggregate;
    private int current = 0;

    // Constructor
    public ConcreteIterator(ConcreteAggregate aggregate)
    {
      this.aggregate = aggregate;
    }

    public override object First()
    {
      return aggregate[0];
    }

    public override object Next()
    {
      object ret = null;
      if (current < aggregate.Count - 1)
      {
        ret = aggregate[++current];
      }
      
      return ret;
    }

    public override object CurrentItem()
    {
      return aggregate[current];
    }

    public override bool IsDone()
    {
      return current >= aggregate.Count ? true : false ;
    }
  }
}

 

Output

Iterating over collection:

Item A

Item B

Item C

Item D

 

This real-world code demonstrates the Iterator pattern which is used to iterate over a collection of items and skip a specific number of items each iteration.

// Iterator pattern -- Real World example

 

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Iterator.RealWorld
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      // Build a collection
      Collection collection = new Collection();
      collection[0] = new Item("Item 0");
      collection[1] = new Item("Item 1");
      collection[2] = new Item("Item 2");
      collection[3] = new Item("Item 3");
      collection[4] = new Item("Item 4");
      collection[5] = new Item("Item 5");
      collection[6] = new Item("Item 6");
      collection[7] = new Item("Item 7");
      collection[8] = new Item("Item 8");

      // Create iterator
      Iterator iterator = new Iterator(collection);

      // Skip every other item
      iterator.Step = 2;

      Console.WriteLine("Iterating over collection:");

      for(Item item = iterator.First();
        !iterator.IsDone; item = iterator.Next())
      {
        Console.WriteLine(item.Name);
      }

      // Wait for user
      Console.Read();
    }
  }

  class Item
  {
    string name;

    // Constructor
    public Item(string name)
    {
      this.name = name;
    }

    // Property
    public string Name
    {
      get{ return name; }
    }
  }

  // "Aggregate"

  interface IAbstractCollection
  {
    Iterator CreateIterator();
  }

  // "ConcreteAggregate"

  class Collection : IAbstractCollection
  {
    private ArrayList items = new ArrayList();

    public Iterator CreateIterator()
    {
      return new Iterator(this);
    }

    // Property
    public int Count
    {
      get{ return items.Count; }
    }
    
    // Indexer
    public object this[int index]
    {
      get{ return items[index]; }
      set{ items.Add(value); }
    }
  }

  // "Iterator"

  interface IAbstractIterator
  {
    Item First();
    Item Next();
    bool IsDone{ get; }
    Item CurrentItem{ get; }
  }

  // "ConcreteIterator"

  class Iterator : IAbstractIterator
  {
    private Collection collection;
    private int current = 0;
    private int step = 1;

    // Constructor
    public Iterator(Collection collection)
    {
      this.collection = collection;
    }

    public Item First()
    {
      current = 0;
      return collection[current] as Item;
    }

    public Item Next()
    {
      current += step;
      if (!IsDone)
        return collection[current] as Item;
      else
        return null;
    }

    // Properties
    public int Step
    {
      get{ return step; }
      set{ step = value; }
    }

    public Item CurrentItem
    {
      get
      {
        return collection[current] as Item;
      }
    }

    public bool IsDone
    {
      get
      {
        return current >= collection.Count ? true : false;
      }
    }
  }
}

 

Output

Iterating over collection:

Item 0

Item 2

Item 4

Item 6

Item 8

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值