はじめに:イテレータパターンは通常、関係なく、C#やJavaのパッケージが私を助けていないので、多くの使用ではありませんが、自然の中で通常のものがしばしば使用されている知っていれば、それが起こったのかです。
イテレータパターンを読んだ後、あなたは、C#のforeachループを達成する方法である、と私の他の1知っているC#のforeach自然のサイクルと列挙子反復モードで使用されているのforeachの性質を説明します。
慣例により、からどこへ行くの例。(数時間をクラッシュブラウザを書く、オートセーブでIソーは、ああ、結果はそれを再び合理化ポイントをロールアップし、内容ませんでした)
まず、合併のレストランのメニュー
2軒のレストランと、朝食のレストラン、料理のディナーがあります。彼らはすべてのメニューを管理する独自の方法を持って、そして今私はそれらの元の外観を見てみましょう、2つのレストランのメニュー統合管理をマージする必要があります。
メニュー内の2つのメニュー項目は同じです
メニュー項目
パブリッククラスMenuItme { //名字 パブリック文字列名前{取得します。セット; } //描述 パブリック文字列説明{GET。セット; } //是否素菜 公共ブールベジタリアン{取得します。セット; } //价格 公共ダブル価格{取得します。セット; } 公共MenuItme(文字列名、文字列説明、ブールベジタリアン、二重価格){ NAME =名前。 説明=説明。 ベジタリアン=ベジタリアン。 価格=価格。 } }
朝食メニュー、リストの管理を使用し、長さを制限しません。
パブリッククラスBreakFastMenu { プライベートリスト<MenuItme> menuItmes。 パブリックBreakFastMenu() { menuItmes =新しいリスト<MenuItme>(); AddItemメソッド( "梅菜扣肉饼"、 "好吃"、偽、7)。 //菜单项... } 公共のボイドAddItemメソッド(文字列名、文字列の記述、ブールベジタリアン、ダブル価格) { MenuItme menuItme =新しいMenuItme(名前、説明、ベジタリアン、価格)。 menuItmes.Add(menuItme)。 } パブリックリスト<MenuItme> GetMenuItmes() { 戻りmenuItmes。 } }
ディナーメニューは、6の長さを制限し、アレイの管理を使用します
パブリッククラスDinerMenu { 静的読み取り専用INT Max_Items = 6。 プライベートint型numberOfImtes = 0; プライベートMenuItme [] menuItmes。 パブリックDinerMenu() { menuItmes =新しいMenuItme [Max_Items]。 AddItemメソッド( "爆炒癞蛤蟆"、 "讲究火候"、偽、42)。 //菜单项... } 公共のボイドAddItemメソッド(文字列名、文字列の記述、ブールベジタリアン、ダブル価格) { MenuItme menuItme =新しいMenuItme(名前、説明、ベジタリアン、価格)。 IF(numberOfImtes> = Max_Items) { Console.WriteLineを( "菜单已满")。 } { menuItmes [numberOfImtes] = menuItme。 numberOfImtes ++; } } パブリックMenuItme [] GetMenuItmes() { 戻りmenuItmes。 } }
合併の必要性の後の顧客にメニューを朝食と夕食のための2つのレストランを印刷します。
BreakFastMenu breakFastMenu =新しいBreakFastMenu(); 一覧<MenuItme> breakFastMenus = breakFastMenu.GetMenuItmes(); DinerMenu dinerMenuは新しいDinerMenuを()=; MenuItme [] dinerMenus = dinerMenu.GetMenuItmes()。 //打印早餐 ため(INT I = 0、I <breakFastMenus.Count; I ++) { Console.WriteLineを(breakFastMenus [I] .nameの)。 } //打印晚餐 ため(INT iは= 0; I <dinerMenus.Lengthを、I ++) { Console.WriteLineを(dinerMenus [I] .nameの)。 }
この練習では、私たちは常に、印刷したい場合、あなたはまた、2つのメニューをループする必要がある2つのメニュー、ベジタリアン食品に対処する必要があります。
あなたは第三レストランの合併を追加した場合、我々は維持するシステムが困難になります明らかに、このように、サイクルに対処するために3回を必要としています。
我々は改善する方法を見て次に
第二に、改善されたメニューを達成するために
メーターモードは、パッケージの一部を変更することです、変更がここにあることは明らかである:私たちはコレクションをパッケージ化する方法によって引き起こさ異なるコレクションをトラバース
朝食や夕食のかどうか、私たちは、長さを制限するために、コレクションの長さを、メニュー項目を取るために、すべての角括弧を[]使用しています。
今、私たちは、彼が反復子(イテレータ)と呼ばれる、オブジェクトを作成する必要がパッケージ化するためにそれを使用する「コレクション内の各オブジェクトのトラバーサルを。」
リストについて
反復子反復子= breakFastMenu.CreateIterator()。 一方、(iterator.HasNext) { MenuItme menuItme = iterator.Next()。 }
アレイの場合
反復子反復子= dinerFastMenu.CreateIterator()。 一方、(iterator.HasNext) { MenuItme menuItme = iterator.Next()。 }
今、二人はコレクションを統一されており、これは双方向イテレータパターンです。私たちが知っている必要がありイテレータについての最初の事は、それがIteratorインターフェイスに依存しているということです。
私たちは、このコレクションの要素のより高い番号を持っている場合は、このインターフェイスは、のhasNext()メソッドを持つことができます。
next()メソッドは、コレクション内の次のオブジェクトを返します。私たちは、このインタフェースを作成したら、オブジェクトのさまざまなコレクションは、それはイテレータを実装することができます。
今、私たちは夕食のメニューを変換する必要があり、我々は最初のIteratorインターフェイスを定義する必要があります
パブリックインターフェイスイテレータ { BOOLのhasNext(); オブジェクト次に()。 }
ディナーメニューを追加しましたイテレータ
DinerMenuIteratorクラスパブリック:イテレータ { MenuItme [] menuItmes; INT位置= 0; 公共DinerMenuIterator(MenuItme [] menuItmes) { this.menuItmes = menuItmes; } 公共BOOLのhasNext() { //配列が固定長であるため、配列を確認するだけでなくまた、指定された場所は、空であるかどうかをチェックするの背後にない空のメニュー項目 IF(位置> = menuItmes.Length || menuItmes [位置] == NULL) 偽に戻り、 他の 真のリターン; } パブリックオブジェクト次へ() { menuItme menuItme menuItmes = [位置]; 位置++。 menuItmeを返します。 } }
イテレータ書き換えディナーメニュー付き
パブリッククラスDinerMenu { 静的読み取り専用INT Max_Items = 6。 プライベートint型numberOfImtes = 0; プライベートMenuItme [] menuItmes。 パブリックDinerMenu() { menuItmes =新しいMenuItme [Max_Items]。 AddItemメソッド( "爆炒癞蛤蟆"、 "讲究火候"、偽、42)。 //菜单项... } 公共のボイドAddItemメソッド(文字列名、文字列の記述、ブールベジタリアン、ダブル価格) { MenuItme menuItme =新しいMenuItme(名前、説明、ベジタリアン、価格)。 IF(numberOfImtes> = Max_Items) { Console.WriteLineを( "菜单已满")。 } 他 { menuItmes [numberOfImtes] = menuItme。 numberOfImtes ++; } } 公共イテレータCreateIterator() { リターン新しいDinerMenuIterator(menuItmes)。 } //パブリックMenuItme [] GetMenuItmes() // { //戻りmenuItmes。 //} }
同様に、私たちは朝食にイテレータを追加します
パブリッククラスBreakFastIterator:イテレータ { 一覧<MenuItme> menuItmes。 int型の位置= 0; 公共BreakFastIterator(一覧<MenuItme> menuItmes) { this.menuItmes = menuItmes。 } パブリックブールのhasNext() { IF(位置> = menuItmes.Count) リターン偽。 他の リターンはtrue。 } パブリックオブジェクト次に() { MenuItme menuItme = menuItmes [位置]。 位置++; menuItmeを返します。 } }
イテレータ書き換え朝食メニュー付き
パブリッククラスBreakFastMenu { プライベートリスト<MenuItme> menuItmes。 パブリックBreakFastMenu() { menuItmes =新しいリスト<MenuItme>(); AddItemメソッド( "梅菜扣肉饼"、 "好吃"、偽、7)。 //菜单项... } 公共のボイドAddItemメソッド(文字列名、文字列の記述、ブールベジタリアン、ダブル価格) { MenuItme menuItme =新しいMenuItme(名前、説明、ベジタリアン、価格)。 menuItmes.Add(menuItme)。 } 公共イテレータCreateIterator() { リターン新しいBreakFastIterator(menuItmes)。 } //パブリックリスト<MenuItme> // { //戻りmenuItmes。 //} }
まあ、聞かせてのは、イテレータの仕事をしてみてください
第三に、イテレータパターン
第二段階の後、私たちは、基本的なイテレータパターンを達成している、そして最終的に我々は改善印刷メニュー、メニュー管理と統一されたインタフェースを見てみましょう。
メニューインタフェースを定義
パブリックインターフェースメニュー { イテレータCreateIterator()。 }
ましょう朝食と夕食は、メニュー・インタフェースを実現しており、パッケージには、新しいメニューを印刷します
public class NewMenu { Menu breakFastMenu; Menu dinerMenu; public NewMenu(Menu breakFastMenu, Menu dinerMenu) { this.breakFastMenu = breakFastMenu; this.dinerMenu = dinerMenu; } public void PrintMenu() { Iterator breakFastIterator = breakFastMenu.CreateIterator(); Console.WriteLine("新菜单--------早餐"); PrintMenu(breakFastIterator); Console.WriteLine("新菜单--------晚餐"); Iterator dinerIterator = dinerMenu.CreateIterator(); PrintMenu(dinerIterator); } private void PrintMenu(Iterator iterator) { while (iterator.HasNext()) { //取得下一个项 MenuItme menuItme = (MenuItme)iterator.Next(); Console.WriteLine(menuItme.Name); } } }
迭代器模式定义:
迭代器模式:提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式让我们能游走于集合内的每一个元素,而又不暴露其内部的表示。
把游走的任务放在迭代器上,而不是集合上。这样简化了集合的接口和实现,也让责任各得其所。