初涉c#设计模式-Iterator Pattern
一、迭代器模式簡介(Brief Introduction)
迭代器模式(Iterator Pattern),提供一種方法順序訪問一個聚合對象中元素,而不暴露改集合對象的內(nèi)部表示。
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
二、解決的問題(What To Solve)
????? 在軟件構(gòu)建過程中,集合對象內(nèi)部結(jié)構(gòu)常常變化各異。但對于這些集合對象,我們希望在不暴露其內(nèi)部結(jié)構(gòu)的同時,可以讓外部客戶代碼透明地訪問其中包含的元素;同時這種“透明遍歷”也為“同一種算法在多種集合對象上進(jìn)行操作”提供了可能。
當(dāng)需要訪問一個聚集對象,而且不管這些對象是什么都需要遍歷的時候,應(yīng)該考慮用迭代器模式;當(dāng)需要對聚集有多種方式遍歷時,可以考慮使用迭代器模式。其中,你不用關(guān)心到底是什么樣子的數(shù)組作為對象集合,是Array,是List還是簡單的數(shù)組,迭代器模式會提供給你一個聚合對象的遍歷方式,而不用去了解具體是在遍歷什么類型的聚合對象。
三、代碼:
View Code using System; using System.Collections.Generic; using System.Text;namespace IteratePattern {public class Guest{public string id{get;set;}public string name{get;set;}public Guest(string aId, string aName){id = aId;name = aName;}}public interface IAggrate{IIterator GetIterator();}public class ConcreateAggrate:IAggrate{List<object> _guest = new List<object>();public IIterator GetIterator(){return new ConcreateIterator(this);}public object this[int index]{get{return _guest[index];}set{_guest.Add(value);}}public int count(){return _guest.Count;}}public interface IIterator{bool Next();}class ConcreateIterator : IIterator{ConcreateAggrate _aggrate;int currentindex;public ConcreateIterator(ConcreateAggrate aAggrate){_aggrate = aAggrate;currentindex = -1;}public object Current{get { return _aggrate[currentindex]; }}public bool Next(){currentindex++;return _aggrate.count() > currentindex;}}class Program{static void Main(string[] args){ConcreateAggrate aAggrate = new ConcreateAggrate();aAggrate[0] = new Guest("1", "hi");aAggrate[1] = new Guest("2", "my");aAggrate[2] = new Guest("3", "dear");aAggrate[3] = new Guest("4", "iterator");aAggrate[4] = new Guest("5", "pattern");//ConcreateIterator aIterator = new ConcreateIterator(aAggrate);ConcreateIterator aIterator = (ConcreateIterator)aAggrate.GetIterator();while (aIterator.Next())Console.WriteLine(((Guest)aIterator.Current).name);}} }?
舉例Iterator應(yīng)用
下面是迭代器所擁有的最小集合,Current是屬性,只能Get不能Set。還有兩個方法:MoveNext是往下一個元素走,如果訪問到最后一個元素之后沒有元素了,就返回False;Reset是復(fù)位,回到初始位置。
如果有一個容器實現(xiàn)了IEnumerable接口,它就可以支持我們的迭代操作了。這種設(shè)計模式已經(jīng)內(nèi)化為C#語言的一種元素了,就是Foreach關(guān)鍵字。我們定義的容器首先要實現(xiàn)IEnumerable接口,實現(xiàn)的GetEnumerator方法要返回一個IEnumerator的類型的集合。
View Code using System; using System.Collections.Generic; using System.Text; using System.Collections;namespace IteratePattern {public class Guest{public string id{get;set;}public string name{get;set;}public Guest(string aId, string aName){id = aId;name = aName;}}public class ConcreateAggrate:IEnumerable{List<object> _guest = new List<object>();public object this[int index]{get{return _guest[index];}set{_guest.Add(value);}}public int count(){return _guest.Count;}#region IEnumerable 成員IEnumerator IEnumerable.GetEnumerator(){return new ConcreateIterator(this);}#endregion}class ConcreateIterator : IEnumerator{ConcreateAggrate _aggrate;int currentindex;public ConcreateIterator(ConcreateAggrate aAggrate){_aggrate = aAggrate;currentindex = -1;}#region IEnumerator 成員object IEnumerator.Current{get { return _aggrate[currentindex]; }}bool IEnumerator.MoveNext(){currentindex++;return _aggrate.count() > currentindex;}void IEnumerator.Reset(){currentindex = -1;}#endregion}class Program{static void Main(string[] args){ConcreateAggrate aAggrate = new ConcreateAggrate();aAggrate[0] = new Guest("1", "hi");aAggrate[1] = new Guest("2", "my");aAggrate[2] = new Guest("3", "dear");aAggrate[3] = new Guest("4", "iterator");aAggrate[4] = new Guest("5", "pattern");foreach (Guest aGuest in aAggrate)Console.WriteLine(aGuest.name);}} }?
Foreach的工作機(jī)制
IEnumerator ietor = aAggrate.GetEnumerator();while(ietor.MoveNext()){Guest aGuest = (Guest)ietor.Current;Console.WriteLine(aGuest);}?
?
遍歷代碼中訪問的全部是接口,而不用關(guān)心集合的內(nèi)部結(jié)構(gòu)。上面的代碼等同于下面的Foreach。
結(jié)構(gòu)(Structure)
?
Iterator模式的幾個要點
迭代抽象:訪問一個聚合對象的內(nèi)容而無需暴露它的內(nèi)部表示。迭代多態(tài):為遍歷不同的集合結(jié)構(gòu)提供一個統(tǒng)一的接口,從而支持同樣的算法在不同的集合結(jié)構(gòu)上進(jìn)行操作。例如假設(shè)我們有一個求和算法
它可以操作在多個支持迭代器的集合上,如果把這個算法寫成ArrayList的話,就會非常受限制。同時我們更可以用C#的Foreach語句來寫。
我們的算法應(yīng)該是獨立的,寫的時候應(yīng)該盡量操作接口,這樣我們寫好一個算法,就能應(yīng)對N種集合的變化,使得同樣的算法能在不同的集合上操作。迭代器的健壯性考慮:遍歷的同時更改迭代器所在的集合結(jié)構(gòu),會導(dǎo)致問題。也就是說,我們在迭代的時候,應(yīng)該只是讀取操作,不能更改容器的接口,例如遍歷的時候刪除一個元素,這樣是不可以的。容器的結(jié)構(gòu)師絕對不能碰的,一旦結(jié)構(gòu)更改,遍歷就會出問題。
下面這種情況對i進(jìn)行更改,是不會影響原來的數(shù)組內(nèi)容的,因為i是int類型,它只是一份拷貝。
我們一定要給用戶提供盡量純只讀的迭代。保證每個元素被且只被遍歷一次。
(引自:山天大畜博客園,http://www.cnblogs.com/cdts_change/archive/2010/10/17/1853689.html)
總結(jié)(Conclusion)
從上面的幾個示例中就可以看出,盡管我們沒有顯示的引用迭代器,但實質(zhì)還是通過迭代器來遍歷的。總地來說,迭代器模式就是分離了集合對象的迭代行為,抽象出一個迭代器類來負(fù)責(zé),這樣既可做到不暴露集合的內(nèi)部結(jié)構(gòu),又可以讓外部代碼可以透明的訪問集合內(nèi)部的元素。
迭代器模式在訪問數(shù)組、集合、列表等數(shù)據(jù)時,尤其是數(shù)據(jù)庫數(shù)據(jù)操作時,是非常普遍的應(yīng)用,但由于它太普遍了,所以各種高級語言都對他進(jìn)行了封裝,所以反而給人感覺此模式本身不太常用了。
?
轉(zhuǎn)載請注明出處:Edward_jie,http://www.cnblogs.com/promise-7/archive/2012/05/28/2521918.html
總結(jié)
以上是生活随笔為你收集整理的初涉c#设计模式-Iterator Pattern的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos更改MySQL数据库目录位置
- 下一篇: Http的轻微配置