迭代器模式介紹

迭代器模式是一種行為設計模式,讓你能在不暴露集合底層表現形式(串列、堆疊、樹等)的情況下遍歷集合中所有的元素,
迭代器模式滿足了單一職責和開閉原則,外界的呼叫方也不需要知道任何一個不同的資料結構在使用上的遍歷差異,
迭代器模式的主要思想是將集合的遍歷行為抽取為單獨的迭代器物件,
除實作自身演算法外,迭代器還封裝了遍歷操作的所有細節,比如當前位置和末尾剩余元素的數量、同時還有提供一個獲取集合元素的基本方法,客戶端可不斷呼叫該方法直到它不回傳任何內容(已遍歷所有元素)、所有迭代器必須實作相同的介面(只要有合適的迭代器,客戶端代碼就能兼容任何型別的集合或遍歷演算法),
迭代器的結構
-
迭代器介面: 宣告了遍歷集合所需的操作,(獲取下一個元素,獲取當前位置和重新開始迭代等)
-
具體迭代者:實作遍歷集合的一種特定演算法,(迭代器必須跟蹤自身遍歷的進度)
-
集合介面:宣告一個或多個方法來獲取與集合兼容的迭代器,(回傳方法的型別必須被宣告為迭代器介面,因此具體集合可以回傳各種不同種類的迭代器)
-
具體集合:會在客戶端請求迭代器時回傳一個特定的具體迭代器類,
-
客戶端:通過集合和迭代器的介面與兩者進行互動,這樣一來客戶端無需與具體類進行耦合,允許同一客戶端代碼使用各種不同的集合和迭代器,
應用場景
- 當集合背后為復雜的資料結構,且你希望對客戶端隱藏其復雜性時,
- 想避免程式中重復的遍歷代碼
- 程式代碼能夠遍歷不同的甚至是無法預知的資料結構時,
實作方式
1、宣告迭代器介面
2、宣告集合介面并描述一個獲取迭代器的方法,其回傳值必須是迭代器介面,
3、為希望使用迭代器遍歷的集合實作具體的迭代器類,
4、在你的集合類中實作集合介面,
5、在客戶端使用迭代器替代所有集合遍歷代碼,
Demo
在迭代器的幫助下,客戶端可以用一個迭代器介面以相似的方式遍歷不同集合中的元素,
迭代器模式的辨別
- 迭代器可以通過導航方法(next和previous)來輕松識別,
- 使用迭代器的客戶端代碼可能沒有其所遍歷的集合的直接訪問權限(二者是完全分離的),
下面羅列了一個對人員集合進行排序的迭代器模式,
人員迭代器
/// <summary>
/// 人員迭代器
/// 繼承介面IEnumerator,顯示實作了Current、MoveNext、Reset方法,
/// </summary>
abstract class PeopleIterator:IEnumerator
{
public abstract int Key();
public abstract object Current();
public abstract bool MoveNext();
public abstract void Reset();
object IEnumerator.Current
{
get { return Current(); }
}
}
抽象集合迭代器和其實作
/// <summary>
/// 抽象的集合迭代器
/// </summary>
public abstract class AggregateIterator :IEnumerable
{
/// <summary>
/// 得到內部的集合
/// </summary>
/// <returns></returns>
public abstract IEnumerator GetEnumerator();
}
/// <summary>
/// 集合的迭代器類
/// 具體排序的邏輯在這里寫著
/// </summary>
class AlphabeticalOrderIterator : PeopleIterator
{
private PeopleCollection _collection;
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(PeopleCollection collection,bool reverse=false)
{
this._collection = collection;
_reverse = reverse;
if (reverse)
{
_position = collection.getItems().Count;
}
}
/// <summary>
/// 當前的值
/// </summary>
/// <returns></returns>
public override object Current()
{
return this._collection.getItems()[_position];
}
/// <summary>
/// 此時的索引
/// </summary>
/// <returns></returns>
public override int Key()
{
return this._position;
}
/// <summary>
/// 下一個 位置position進行調整
/// </summary>
/// <returns></returns>
public override bool MoveNext()
{
int updatedPosition = this._position + (this._reverse ? -1 : 1);
if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
{
this._position = updatedPosition;
return true;
}
else
{
return false;
}
}
/// <summary>
/// 重置
/// </summary>
public override void Reset()
{
this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
}
}
具體的人員集合和其Main()方法驗證
/// <summary>
/// 具體的人員集合
/// </summary>
public class PeopleCollection :AggregateIterator
{
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);
}
}
class Program
{
static void Main(string[] args)
{
var collection = new PeopleCollection();
collection.AddItem("阿五");
collection.AddItem("阿六");
collection.AddItem("阿七");
Console.WriteLine("遍歷下");
foreach (var item in collection)
{
Console.WriteLine(item);
}
Console.WriteLine("倒序");
collection.ReverseDirection();
foreach (var item in collection)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}

迭代器模式在理解上還是有一點難度的,因為平時在使用集合時各個語言都已經將集合的各種操作方法都已經羅列出來了,呼叫人員直觀呼叫即可,所以我們在了解其設計模式思想時,還是要多進行實踐和思考,
有些東西看的多了,做的多了,自然而然就明白了,
小寄語
人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的,
原創不易,給個關注,
我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩關注、點贊、轉發 謝謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/294828.html
標籤:.NET技术
上一篇:[WPF] 使用 MVVM Toolkit 構建 MVVM 程式
下一篇:C# 入門實戰系列文章
