迭代器模式
迭代器在日常生活中也有应用,比如我们去超市买完东西然后排队结账,收银员只需要扫描商品上的条形码就知道商品价格,而不用关系到底是什么商品,在程序中的,各种List,Collection等也都采用了迭代器的思想。
意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
其主要优点如下。
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 遍历任务交由迭代器完成,这简化了聚合类。
- 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
- 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
- 封装性良好,为遍历不同的聚合结构提供一个统一的接口。
其主要缺点是:
- 增加了类的个数,这在一定程度上增加了系统的复杂性。
类图如下。
完整代码如下。
using System;
using System.Collections;
using System.Collections.Generic;
namespace _15_Iterator
{
class Program
{
/// <summary>
/// 迭代器模式
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
var collection = new WordsCollection();
collection.AddItem("First");
collection.AddItem("Second");
collection.AddItem("Third");
Console.WriteLine("Straight traversal:");
foreach (var elment in collection)
{
Console.WriteLine(elment);
}
Console.WriteLine("\nReverse traversal:");
collection.ReverseDirection();
foreach (var element in collection)
{
Console.WriteLine(element);
}
Console.ReadKey();
}
}
abstract class Iterator : IEnumerator
{
object IEnumerator.Current => Current();
public abstract int Key();
public abstract object Current();
public abstract bool MoveNext();
public abstract void Reset();
}
abstract class IteratorAggregate : IEnumerable
{
public abstract IEnumerator GetEnumerator();
}
class AlphabeticalOrderIterator : Iterator
{
private WordsCollection _collection;
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(WordsCollection collection,bool reverse=false)
{
_collection = collection;
_reverse = reverse;
if (reverse)
{
_position = collection.GetItems().Count;
}
}
public override object Current()
{
return _collection.GetItems()[_position];
}
public override int Key()
{
return _position;
}
public override bool MoveNext()
{
int updatedPosition = _position + (_reverse ? -1 : 1);
if(updatedPosition>=0 && updatedPosition < _collection.GetItems().Count)
{
_position = updatedPosition;
return true;
}
else
{
return false;
}
}
public override void Reset()
{
_position = _reverse ? _collection.GetItems().Count - 1 : 0;
}
}
class WordsCollection : IteratorAggregate
{
List<string> _collection = new List<string>();
bool _direction = false;
public void ReverseDirection()
{
_direction = !_direction;
}
public List<string> GetItems()
{
return _collection;
}
public void AddItem(string item)
{
_collection.Add(item);
}
public override IEnumerator GetEnumerator()
{
return new AlphabeticalOrderIterator(this, _direction);
}
}
}
一般我们所用的语言中的List,Collention,Map 等集合类,都已经包含了迭代器,无需自己实现。