# 设计模式（十七）—— 迭代器模式

## 结构分析

### 角色说明

• Aggregate

• ConcreteAggregate

• Iterator

• ConcreteIterator

### 工作原理

ConcreteIterator跟踪聚合中的当前对象，通过Next方法计算出待遍历的下一个对象。

### 结构代码

//抽象迭代器
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}

//抽象聚合类
abstract class Aggregate
{
public abstract Iterator CreateIterator();
}

//实际聚合类，实现Aggregate中的抽象方法CreateIterator，返回相应的迭代器
class ConcreteAggregate : Aggregate
{
private ArrayList _items = new ArrayList();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}

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

public int Count
{
get { return _items.Count; }
}
}

//实际迭代器
class ConcreteIterator : Iterator
{
private ConcreteAggregate _aggregate;
private int _current;
public ConcreteIterator(ConcreteAggregate aggregate)
{
_aggregate = aggregate;
}
public override object CurrentItem()
{
return _aggregate[_current];
}

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

public override bool IsDone()
{
return _current >= _aggregate.Count - 1;
}

public override object Next()
{
object next = null;
if (_current < _aggregate.Count - 1)
{
next = _aggregate[++_current];
}
return next;
}
}

//客户端调用
static void Main(string[] args)
{
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate[0] = "A";
aggregate[1] = "B";
aggregate[2] = "C";
aggregate[3] = "D";

var iterator = aggregate.CreateIterator();
Console.WriteLine(iterator.First());
while (!iterator.IsDone())
{
Console.WriteLine(iterator.Next());
}
}

## 示例分析

class Song
{
public string Name { get; set; }
public string Singer { get; set; }
}

interface Iterator
{
object First();
object Next();
bool IsDone();
object CurrentItem();
}

interface IAggregate
{
Iterator CreateIterator();
}

class SongIterator : Iterator
{
private SongCollection _songCollection;
private int _current;

public SongIterator(SongCollection songCollection)
{
this._songCollection = songCollection;
}

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

public object Next()
{
object song = null;
if (_current < _songCollection.Count - 1)
{
song = _songCollection[++_current];
}
return song;
}

public bool IsDone()
{
return _current >= _songCollection.Count - 1;
}

public object CurrentItem()
{
return _songCollection[_current];
}
}

class SongCollection : IAggregate
{
private ArrayList _songs = new ArrayList();
public Iterator CreateIterator()
{
return new SongIterator(this);
}

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

public int Count
{
get { return _songs.Count; }
}
}

class Program
{
static void Main(string[] args)
{
SongCollection songs = new SongCollection();
songs[0] = new Song { Name = "Dance To This", Singer = "Troye Sivan" };
songs[1] = new Song { Name = "Ferrari", Singer = "Bebe Rexha" };
songs[2] = new Song { Name = "Ocean", Singer = "Martin Garrix" };
songs[3] = new Song { Name = "Sober", Singer = "Demi Lovato" };
songs[4] = new Song { Name = "Only You", Singer = "Cheat Codes" };

Iterator iterator = songs.CreateIterator();
var firstSong = iterator.First() as Song;
Console.WriteLine($"First Song：{firstSong.Name},Singer：{firstSong.Singer}"); while (!iterator.IsDone()) { var currentSong = iterator.Next() as Song; Console.WriteLine($"Now Playing：{ currentSong.Name},Singer：{currentSong.Singer}");
}
}
}

List<Song> songs = new List<Song>();
songs.Add(new Song { Name = "Dance To This", Singer = "Troye Sivan" });
songs.Add(new Song { Name = "Ferrari", Singer = "Bebe Rexha" });
songs.Add(new Song { Name = "Ocean", Singer = "Martin Garrix" });
songs.Add(new Song { Name = "Sober", Singer = "Demi Lovato" });
songs.Add(new Song { Name = "Only You", Singer = "Cheat Codes" });

foreach (var song in songs)
{
Console.WriteLine(\$"Now Playing：{ song.Name},Singer：{song.Singer}");
}

## 使用场景

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

• 支持对聚合对象的多种遍历。
• 为遍历不同的聚合结构提供一个统一的接口。

posted @ 2018-06-28 20:54 Answer.Geng 阅读(...) 评论(...) 编辑 收藏