疊代器模式
疊代器在日常生活中也有應用,比如我們去超市買完東西然後排隊結賬,收銀員隻需要掃描商品上的條形碼就知道商品價格,而不用關系到底是什麼商品,在程式中的,各種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 等集合類,都已經包含了疊代器,無需自己實作。