目錄
- 定義與特點
- 結構與實作
- 模式的結構
- 模式的實作
- 應用場景
- 擴展:與組合模式結合
在現實生活以及程式設計中,經常要訪問一個聚合物件中的各個元素,如“資料結構”中的鏈表遍歷,通常的做法是將鏈表的創建和遍歷都放在同一個類中,但這種方式不利于程式的擴展,如果要更換遍歷方法就必須修改程式源代碼,這違背了 “開閉原則”,
既然將遍歷方法封裝在聚合類中不可取,那么聚合類中不提供遍歷方法,將遍歷方法由用戶自己實作是否可行呢?答案是同樣不可取,因為這種方式會存在兩個缺點:
- 暴露了聚合類的內部表示,使其資料不安全,
- 增加了客戶的負擔,
“迭代器模式”能較好地克服以上缺點,它在客戶訪問類與聚合類之間插入一個迭代器,這分離了聚合物件與其遍歷行為,對客戶也隱藏了其內部細節,且滿足“單一職責原則”和“開閉原則”,
定義與特點
迭代器(Iterator)模式的定義:提供一個物件來順序訪問聚合物件中的一系列資料,而不暴露聚合物件的內部表示,
迭代器模式是一種物件行為型模式,其主要優點如下:
- 訪問一個聚合物件的內容而無須暴露它的內部表示,
- 遍歷任務交由迭代器完成,這簡化了聚合類,
- 它支持以不同方式遍歷一個聚合,甚至可以自定義迭代器的子類以支持新的遍歷,
- 增加新的聚合類和迭代器類都很方便,無須修改原有代碼,
- 封裝性良好,為遍歷不同的聚合結構提供一個統一的介面,
其主要缺點是:增加了類的個數,這在一定程度上增加了系統的復雜性,
結構與實作
迭代器模式是通過將聚合物件的遍歷行為分離出來,抽象成迭代器類來實作的,其目的是在不暴露聚合物件的內部結構的情況下,讓外部代碼透明地訪問聚合的內部資料,
模式的結構
迭代器模式主要包含以下角色:
- 抽象聚合(Aggregate)角色:定義存盤、添加、洗掉聚合物件以及創建迭代器物件的介面,
- 具體聚合(ConcreteAggregate)角色:實作抽象聚合類,回傳一個具體迭代器的實體,
- 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的介面,通常包含 HasNext()、First()、Next() 等方法,
- 具體迭代器(Concretelterator)角色:實作抽象迭代器介面中所定義的方法,完成對聚合物件的遍歷,記錄遍歷的當前位置,
其結構圖如圖所示:

模式的實作
迭代器模式的實作代碼如下:
class Program
{
static void Main(string[] args)
{
IAggregate ag = new ConcreteAggregate();
ag.Add("中山大學");
ag.Add("華南理工");
ag.Add("韶關學院");
Console.WriteLine("聚合的內容有:");
IIterator it = ag.GetIterator();
while (it.HasNext())
{
Object ob = it.Next();
Console.WriteLine(ob.ToString());
}
Console.WriteLine("First:" + it.First().ToString());
Console.Read();
}
}
//抽象聚合
public interface IAggregate
{
void Add(Object obj);
void Remove(Object obj);
IIterator GetIterator();
}
//具體聚合
public class ConcreteAggregate : IAggregate
{
private List<Object> list=new List<Object>();
public void Add(Object obj)
{
list.Add(obj);
}
public void Remove(Object obj)
{
list.Remove(obj);
}
public IIterator GetIterator()
{
return(new ConcreteIterator(list));
}
}
//抽象迭代器
public interface IIterator
{
Object First();
Object Next();
bool HasNext();
}
//具體迭代器
public class ConcreteIterator : IIterator
{
private List<Object> list=null;
private int index=-1;
public ConcreteIterator(List<Object> list)
{
this.list=list;
}
public bool HasNext()
{
if(index<list.Count-1)
{
return true;
}
else
{
return false;
}
}
public Object First()
{
index=0;
Object obj=list[index];;
return obj;
}
public Object Next()
{
Object obj=null;
if(this.HasNext())
{
obj=list[++index];
}
return obj;
}
}
程式運行結果如下:
聚合的內容有:
中山大學
華南理工
韶關學院
First:中山大學
注:在C#中,推薦使用泛型代替Object以降低性能消耗,
應用場景
前面介紹了關于迭代器模式的結構與特點,下面介紹其應用場景,迭代器模式通常在以下幾種情況使用:
- 當需要為聚合物件提供多種遍歷方式時,
- 當需要為遍歷不同的聚合結構提供一個統一的介面時,
- 當訪問一個聚合物件的內容而無須暴露其內部細節的表示時,
由于聚合與迭代器的關系非常密切,所以大多數語言在實作聚合類時都提供了迭代器類,因此大數情況下使用語言中已有的聚合類的迭代器就已經夠了,
擴展:與組合模式結合
迭代器模式常常與組合模式結合起來使用,在對組合模式中的容器構件進行訪問時,經常將迭代器潛藏在組合模式的容器構成類中,當然,也可以構造一個外部迭代器來對容器構件進行訪問,其結構圖如圖所示:

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/1072.html
標籤:設計模式
上一篇:詳解JAVA面向物件的設計模式 (零)、GoF的23種設計模式
下一篇:行為型模式之訪問者模式
