国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
.NET設(shè)計(jì)模式(18):迭代器模式(Iterator Pattern)

概述

在面向?qū)ο蟮能浖O(shè)計(jì)中,我們經(jīng)常會(huì)遇到一類集合對(duì)象,這類集合對(duì)象的內(nèi)部結(jié)構(gòu)可能有著各種各樣的實(shí)現(xiàn),但是歸結(jié)起來,無非有兩點(diǎn)是需要我們?nèi)リP(guān)心的:一是集合內(nèi)部的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),二是遍歷集合內(nèi)部的數(shù)據(jù)。面向?qū)ο笤O(shè)計(jì)原則中有一條是類的單一職責(zé)原則,所以我們要盡可能的去分解這些職責(zé),用不同的類去承擔(dān)不同的職責(zé)。Iterator模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)迭代器類來負(fù)責(zé),這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu),又可讓外部代碼透明的訪問集合內(nèi)部的數(shù)據(jù)。

意圖

提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素, 而又不需暴露該對(duì)象的內(nèi)部表示。[GOF 《設(shè)計(jì)模式》]

結(jié)構(gòu)圖

Iterator模式結(jié)構(gòu)圖如下:

1  Iterator模式結(jié)構(gòu)圖

生活中的例子

迭代器提供一種方法順序訪問一個(gè)集合對(duì)象中各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。在早期的電視機(jī)中,一個(gè)撥盤用來改變頻道。當(dāng)改變頻道時(shí),需要手工轉(zhuǎn)動(dòng)撥盤移過每一個(gè)頻道,而不論這個(gè)頻道是否有信號(hào)。現(xiàn)在的電視機(jī),使用[后一個(gè)][前一個(gè)]按鈕。當(dāng)按下[后一個(gè)]按鈕時(shí),將切換到下一個(gè)預(yù)置的頻道。想象一下在陌生的城市中的旅店中看電視。當(dāng)改變頻道時(shí),重要的不是幾頻道,而是節(jié)目?jī)?nèi)容。如果對(duì)一個(gè)頻道的節(jié)目不感興趣,那么可以換下一個(gè)頻道,而不需要知道它是幾頻道。

2  使用選頻器做例子的Iterator模式對(duì)象圖

Iterator模式解說

在面向?qū)ο蟮能浖O(shè)計(jì)中,我們經(jīng)常會(huì)遇到一類集合對(duì)象,這類集合對(duì)象的內(nèi)部結(jié)構(gòu)可能有著各種各樣的實(shí)現(xiàn),但是歸結(jié)起來,無非有兩點(diǎn)是需要我們?nèi)リP(guān)心的:一是集合內(nèi)部的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),二是遍歷集合內(nèi)部的數(shù)據(jù)。面向?qū)ο笤O(shè)計(jì)原則中有一條是類的單一職責(zé)原則,所以我們要盡可能的去分解這些職責(zé),用不同的類去承擔(dān)不同的職責(zé)。Iterator模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)迭代器類來負(fù)責(zé),這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu),又可讓外部代碼透明的訪問集合內(nèi)部的數(shù)據(jù)。下面看一個(gè)簡(jiǎn)單的示意性例子,類結(jié)構(gòu)圖如下:

3 示例代碼結(jié)構(gòu)圖

首先有一個(gè)抽象的聚集,所謂的聚集就是就是數(shù)據(jù)的集合,可以循環(huán)去訪問它。它只有一個(gè)方法GetIterator()讓子類去實(shí)現(xiàn),用來獲得一個(gè)迭代器對(duì)象。

/// <summary>

/// 抽象聚集

/// </summary>


public interface IList

{
    IIterator GetIterator();
}

抽象的迭代器,它是用來訪問聚集的類,封裝了一些方法,用來把聚集中的數(shù)據(jù)按順序讀取出來。通常會(huì)有MoveNext()、CurrentItem()Fisrt()、Next()等幾個(gè)方法讓子類去實(shí)現(xiàn)。

/// <summary>

/// 抽象迭代器

/// </summary>


public interface IIterator
{
    
bool MoveNext();

    Object CurrentItem();

    
void First();

    
void Next();
}

具體的聚集,它實(shí)現(xiàn)了抽象聚集中的唯一的方法,同時(shí)在里面保存了一組數(shù)據(jù),這里我們加上Length屬性和GetElement()方法是為了便于訪問聚集中的數(shù)據(jù)。

/// <summary>

/// 具體聚集

/// </summary>


public class ConcreteList : IList
{
    
int[] list;

    
public ConcreteList()

  
{
        list 
= new int[]1,2,3,4,5};
    }


    
public IIterator GetIterator()

  
{
        
return new ConcreteIterator(this);
    }


    
public int Length

  
{
        
getreturn list.Length; }
    }


    
public int GetElement(int index)

  
{
        
return list[index];
    }

}

具體迭代器,實(shí)現(xiàn)了抽象迭代器中的四個(gè)方法,在它的構(gòu)造函數(shù)中需要接受一個(gè)具體聚集類型的參數(shù),在這里面我們可以根據(jù)實(shí)際的情況去編寫不同的迭代方式。

/// <summary>

/// 具體迭代器

/// </summary>


public class ConcreteIterator : IIterator

{
    
private ConcreteList list;

    
private int index;

    
public ConcreteIterator(ConcreteList list)

  
{
        
this.list = list;

        index 
= 0;
    }


    
public bool MoveNext()

  
{
        
if (index < list.Length)

            
return true;

        
else

            
return false;
    }


    
public Object CurrentItem()

  
{
        
return list.GetElement(index) ;
    }


    
public void First()

  
{
        index 
= 0;
    }


    
public void Next()

  
{
        
if (index < list.Length)

      
{
            index
++;
        }

    }

}

簡(jiǎn)單的客戶端程序調(diào)用:

/// <summary>

/// 客戶端程序

/// </summary>


class Program

{
    
static void Main(string[] args)

  
{
        IIterator iterator;

        IList list 
= new ConcreteList();

        iterator 
= list.GetIterator();

        
while (iterator.MoveNext())

      
{
            
int i = (int)iterator.CurrentItem();
            Console.WriteLine(i.ToString());

            iterator.Next();
        }


        Console.Read();

    }


}

一個(gè)簡(jiǎn)單的迭代器示例就結(jié)束了,這里我們并沒有利用任何的.NET特性,在C#中,實(shí)現(xiàn)Iterator模式已經(jīng)不需要這么麻煩了,已經(jīng)C#語言本身就有一些特定的實(shí)現(xiàn),下面會(huì)說到。

.NET中的Iterator模式

.NET下實(shí)現(xiàn)Iterator模式,對(duì)于聚集接口和迭代器接口已經(jīng)存在了,其中IEnumerator扮演的就是迭代器的角色,它的實(shí)現(xiàn)如下:

public interface IEumerator

{
    
object Current
  
{
        
get;
    }


    
bool MoveNext();

    
void Reset();

}

屬性Current返回當(dāng)前集合中的元素,Reset()方法恢復(fù)初始化指向的位置,MoveNext()方法返回值true表示迭代器成功前進(jìn)到集合中的下一個(gè)元素,返回值false表示已經(jīng)位于集合的末尾。能夠提供元素遍歷的集合對(duì)象,在.Net中都實(shí)現(xiàn)了IEnumerator接口。

IEnumerable則扮演的就是抽象聚集的角色,只有一個(gè)GetEnumerator()方法,如果集合對(duì)象需要具備跌代遍歷的功能,就必須實(shí)現(xiàn)該接口。

public interface IEnumerable

{
    IEumerator GetEnumerator();
}

下面看一個(gè)在.NET1.1下的迭代器例子,Person類是一個(gè)可枚舉的類。PersonsEnumerator類是一個(gè)枚舉器類。這個(gè)例子來自于http://www.theserverside.net/,被我簡(jiǎn)單的改造了一下。

public class Persons : IEnumerable 


    
public string[] m_Names; 

    
public Persons(params string[] Names) 
  

        m_Names 
= new string[Names.Length]; 

        Names.CopyTo(m_Names,
0); 
    }
 

    
private string this[int index] 
  

        
get 
      

            
return m_Names[index]; 
        }
 

        
set 
      

            m_Names[index] 
= value; 
        }
 
    }


    
public IEnumerator GetEnumerator()
  
{
        
return new PersonsEnumerator(this);
    }

}



public class PersonsEnumerator : IEnumerator
{
    
private int index = -1;

    
private Persons P;

    
public PersonsEnumerator(Persons P)
  
{
        
this.P = P;
    }


    
public bool MoveNext()
  
{
        index
++;

        
return index < P.m_Names.Length;
    }


    
public void Reset()
 
{
        index 
= -1;
    }


    
public object Current
  
{
        
get

      
{
            
return P.m_Names[index];
        }

    }

}
 

來看客戶端代碼的調(diào)用:

class Program 

    
static void Main(string[] args) 
  

        Persons arrPersons 
= new Persons("Michel","Christine","Mathieu","Julien"); 

        
foreach (string s in arrPersons) 

      

            Console.WriteLine(s); 
        }


        Console.ReadLine(); 
    }
 
}

程序?qū)⑤敵觯?/span>

Michel 

Christine 

Mathieu 

Julien

現(xiàn)在我們分析編譯器在執(zhí)行foreach語句時(shí)到底做了什么,它執(zhí)行的代碼大致如下:

class Program 


    
static void Main(string[] args) 
  

          Persons arrPersons 
= new Persons("Michel","Christine","Mathieu","Julien"); 

          IEnumerator e 
= arrPersons.GetEnumerator(); 

          
while (e.MoveNext()) 
        

            Console.WriteLine((
string)e.Current); 

          }


          Console.ReadLine();
    }
 
}

可以看到這段代碼跟我們最前面提到的示例代碼非常的相似。同時(shí)在這個(gè)例子中,我們把大部分的精力都花在了實(shí)現(xiàn)迭代器和可迭代的類上面,在.NET2.0下面,由于有了yield return關(guān)鍵字,實(shí)現(xiàn)起來將更加的簡(jiǎn)單優(yōu)雅。下面我們把剛才的例子在2.0下重新實(shí)現(xiàn)一遍:

public class Persons : IEnumerable 

    
string[] m_Names; 

    
public Persons(params string[] Names) 
  

        m_Names 
= new string[Names.Length]; 

        Names.CopyTo(m_Names,
0); 
    }
 

    
public IEnumerator GetEnumerator() 
  

        
foreach (string s in m_Names) 
      

            yield 
return s; 
        }
 
    }
 
}
 

class Program 

    
static void Main(string[] args) 
    

        Persons arrPersons 
= new Persons("Michel","Christine","Mathieu","Julien"); 

        
foreach (string s in arrPersons) 
      

            Console.WriteLine(s); 
        }


        Console.ReadLine(); 
    }
 
}

程序?qū)⑤敵觯?/span>

Michel 

Christine 

Mathieu 

Julien

實(shí)現(xiàn)相同的功能,由于有了yield return關(guān)鍵字,變得非常的簡(jiǎn)單。好了,關(guān)于.NET中的Iterator模式就說這么多了,更詳細(xì)的內(nèi)容大家可以參考相關(guān)的資料。

效果及實(shí)現(xiàn)要點(diǎn)

1.迭代抽象:訪問一個(gè)聚合對(duì)象的內(nèi)容而無需暴露它的內(nèi)部表示。

2.迭代多態(tài):為遍歷不同的集合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口,從而支持同樣的算法在不同的集合結(jié)構(gòu)上進(jìn)行操作。

3.迭代器的健壯性考慮:便利的同時(shí)更改迭代器所在的集合結(jié)構(gòu),會(huì)導(dǎo)致問題。

適用性

1.訪問一個(gè)聚合對(duì)象的內(nèi)容而無需暴露它的內(nèi)部表示。

2.支持對(duì)聚合對(duì)象的多種遍歷。

3.為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口(, 支持多態(tài)迭代)。

總結(jié)

Iterator模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)迭代器類來負(fù)責(zé),這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu),又可讓外部代碼透明的訪問集合內(nèi)部的數(shù)據(jù)。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
.Net中的設(shè)計(jì)模式——Iterator模式
C#基礎(chǔ)之yield與Singleton
C#如何實(shí)現(xiàn)自定義集合的IEnumerable 和 IEnumerator 接口并使用foreach訪問自定義集合
IEnumerable和IEnumerator介紹和區(qū)別
C# 中的枚舉器
【C#設(shè)計(jì)模式-迭代器模式】
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服