日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式的征途—21.迭代器(Iterator)模式

發布時間:2025/4/16 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式的征途—21.迭代器(Iterator)模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們都用過電視機遙控器,通過它我們可以進行開機、關機、換臺、改變音量等操作。我們可以將電視機看做一個存儲電視頻道的集合對象,通過遙控器可以對電視機中的頻道集合進行操作,例如返回上一個頻道、跳轉到下一個頻道或者跳轉到指定的頻道等。遙控器的出現,使得用戶不需要知道這些頻道到底如何存儲在電視機中。在軟件開發中也存在類似于電視機一樣的類,他們可以存儲了多個成員對象(元素),這些類通常稱為聚合類(Aggregate Class),對應的對象稱為聚合對象。為了更加方便地操作這些聚合對象,同時可以很靈活地為聚合對象增加不同的遍歷方法,也需要類似于電視機遙控器一樣的角色,可以訪問一個聚合對象中的元素擔憂部需要暴露它的內部結構,這就是我們需要學習的迭代器模式。

迭代器模式(Iterator)學習難度:★★★☆☆使用頻率:★★★★★

一、銷售管理系統中數據的遍歷

Background?: M公司為某商場開發了一套銷售管理系統,在對該系統進行分析和設計時,M公司開發人員發現經常需要對系統中的商品數據、客戶數據等進行遍歷,為了復用這些遍歷代碼,M公司開發人員設計了一個抽象的數據聚合類AbstractObjectList,而將存儲商品和客戶登記的類作為其子類。AbstractObjectList類結構如下圖所示。

在上圖中,IList類型的對象objects用于存儲數據,AbstractObjectList類的方法說明如下表所示:

AbstractObjectList類的子類ProductList和CustomerList分別用于存儲商品數據和客戶數據。

  M公司開發人員通過對AbstractObjectList類結構進行分析,發現該設計方案存在以下問題:

  (1)在該類中,AddObject()與RemoveObject()等方法用于管理數據,而GetNextItem()、GetPreviousItem()、IsFirst()等方法又用于遍歷數據,導致了聚合類的職責過重,違反了單一職責原則。

  (2)如果將抽象聚合類聲明為一個接口,則在這個接口中充斥著大量方法,不利于子類實現,違反了接口隔離原則。

  (3)如果將所有的遍歷操作都交給子類來實現,將導致子類代碼過于龐大,而且必須暴露AbstractObjectList類的內部存儲細節,向子類公開自己的私有屬性,否則子類無法實施對數據的遍歷,將破壞AbstractObjectList類的封裝性。

  如何解決該問題?解決方案之一就是將聚合類中負責遍歷數據的方法提取出來,封裝到專門的類中,實現數據存儲和數據遍歷的分離無須暴露聚合類的內部屬性即可對其進行操作,這正是迭代器模式的意圖所在。

二、迭代器模式概述

2.1 迭代器模式簡介

  在軟件開發中,經常需要使用聚合對象來存儲一系列數據。聚合對象擁有兩個職責:一是存儲數據,二是遍歷數據。從依賴性來看,前者是聚合對象的基本職責,而后者既是可變化的又是可分離的。因此,可以將遍歷數據的行為從聚合對象中分離出來,封裝在一個被稱為“迭代器”的對象中,由迭代器來提供遍歷聚合對象內部數據的行為,這將簡化聚合對象的設計,更加符合單一職責原則。

迭代器(Iterator)模式:提供一種方法來訪問聚合對象,而不用暴露這個對象的內部表示,其別名為游標(Cursor)。迭代器模式是一種對象行為型模式。  

2.2 迭代器模式結構

  (1)Iterator(抽象迭代器):定義了訪問和遍歷元素的接口,聲明了用于遍歷數據元素的方法。

  (2)ConcreteIterator(具體迭代器):它實現了抽象迭代器接口,完成對聚合對象的遍歷。

  (3)Aggregate(抽象聚合類):用于存儲和管理元素對象,聲明一個CreateIterator()方法用于創建一個迭代器對象,充當抽象迭代器工廠角色。

  (4)ConcreteAggregate(具體聚合類):實現了在抽象聚合類中聲明的CreateIterator()方法,返回一個對應的具體迭代器ConcreteIterator實例。

三、銷售管理系統中數據的遍歷實現

3.1 重構后的設計結構

  其中,AbstractObjectList充當抽象聚合類,ProductList充當具體聚合類,AbstractIterator充當抽象迭代器,ProductIterator充當具體迭代器。

3.2 重構后的代碼實現

  (1)抽象聚合類:AbstractObjectList

/// <summary>/// 抽象聚合類:AbstractObjectList/// </summary>public abstract class AbstractObjectList{protected IList<object> objectList = new List<object>();public AbstractObjectList (IList<object> objectList){this.objectList = objectList;}public void AddObject(object obj){this.objectList.Add(obj);}public void RemoveObject(object obj){this.objectList.Remove(obj);}public IList<Object> GetObjectList(){return this.objectList;}// 聲明創建迭代器對象的抽象工廠方法public abstract AbstractIterator CreateIterator();}

  (2)具體聚合類 - ProductList 與?具體迭代器 - ProductIterator => 這里采用了內部類的方式

/// <summary>/// 具體聚合類:ProductList/// </summary>public class ProductList : AbstractObjectList{public ProductList(IList<object> objectList) : base(objectList){}public override AbstractIterator CreateIterator(){return new ProductIterator(this);}/// <summary>/// 內部類=>具體迭代器:ProductIterator/// </summary>private class ProductIterator : AbstractIterator{private ProductList productList;private IList<object> products;private int cursor1; // 定義一個游標,用于記錄正向遍歷的位置private int cursor2; // 定義一個游標,用于記錄逆向遍歷的位置public ProductIterator(ProductList productList){this.productList = productList;this.products = productList.GetObjectList(); // 獲取集合對象this.cursor1 = 0; // 設置正向遍歷游標的初始值this.cursor2 = this.products.Count - 1; // 設置逆向遍歷游標的初始值 }public object GetNextItem(){return products[cursor1];}public object GetPreviousItem(){return products[cursor2];}public bool IsFirst(){return cursor2 == -1;}public bool IsLast(){return cursor1 == products.Count;}public void Next(){if (cursor1 < products.Count){cursor1++;}}public void Previous(){if (cursor2 > -1){cursor2--;}}}}

  (3)抽象迭代器:AbstractIterator

/// <summary>/// 抽象迭代器:AbstractIterator/// </summary>public interface AbstractIterator{void Next(); // 移動至下一個元素bool IsLast(); // 判斷是否為最后一個元素void Previous(); // 移動至上一個元素bool IsFirst(); // 判斷是否為第一個元素object GetNextItem(); // 獲取下一個元素object GetPreviousItem(); // 獲取上一個元素}

  (4)客戶端測試

public class Program{public static void Main(string[] args){IList<object> products = new List<object>();products.Add("倚天劍");products.Add("屠龍刀");products.Add("斷腸草");products.Add("葵花寶典");products.Add("四十二章經");AbstractObjectList objectList = new ProductList(products); // 創建聚合對象AbstractIterator iterator = objectList.CreateIterator(); // 創建迭代器對象 Console.WriteLine("正向遍歷");while (!iterator.IsLast()){Console.Write(iterator.GetNextItem() + ",");iterator.Next();}Console.WriteLine();Console.WriteLine("-------------------------------------------------------");Console.WriteLine("逆向遍歷");while (!iterator.IsFirst()){Console.Write(iterator.GetPreviousItem() + ",");iterator.Previous();}Console.ReadKey();}}

  F5編譯運行后的結果如下圖所示:

  

四、迭代器模式小結

4.1 主要優點

  (1)支持以不同方式遍歷一個聚合對象,在同一個聚合對象上可以定義多種便利方式。

  (2)增加新的聚合類和迭代器類都很方便 => 無須修改原有代碼,符合開閉原則。

4.2 主要缺點

  增加新的聚合類需要對應增加新的迭代器類?=> 類的個數會成對增加!

4.3 應用場景

  (1)訪問一個聚合對象的內容而無須暴露它的內部表示。

  (2)需要為一個聚合對象提供多種遍歷方式。

  (3)重點 =>?該模式在.Net中,可以通過實現IEnumberable接口即可,不再需要單獨實現! (在.NET下,迭代器模式中的聚集接口和迭代器接口都已經存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口則扮演的就是抽象聚集的角色,其中定義了GetEnumerator()方法。)

參考資料

  

  (1)劉偉,《設計模式的藝術—軟件開發人員內功修煉之道》

  (2)圣杰,《C#設計模式之迭代器模式》

?

作者:周旭龍

出處:http://edisonchou.cnblogs.com

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。

轉載于:https://www.cnblogs.com/edisonchou/p/7442138.html

總結

以上是生活随笔為你收集整理的设计模式的征途—21.迭代器(Iterator)模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。