<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        My Github

      設計模式的征途—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()方法。)

      參考資料

        DesignPattern

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

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

       

      posted @ 2017-09-03 19:29  EdisonZhou  閱讀(2593)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 久久综合亚洲色一区二区三区| 中文字幕日韩国产精品| 老鸭窝在线视频| 国产无遮挡又黄又爽高潮| 我要看亚洲黄色太黄一级黄| 久久亚洲国产精品久久| 国产精品午夜福利91| 国色天香中文字幕在线视频| 国产免费福利网站| 国产精品女生自拍第一区| 妺妺窝人体色www看美女| 视频一区二区三区四区久久| 少妇熟女久久综合网色欲| 国色天香成人一区二区| 亚洲伊人久久大香线蕉| 日本另类αv欧美另类aⅴ| 真实国产老熟女无套中出| 蜜桃视频网站| 丰满少妇特黄一区二区三区| 麻豆精品一区二区综合av| 动漫AV纯肉无码AV电影网| 人妻性奴波多野结衣无码| 亚洲中文久久久精品无码| 日韩区中文字幕在线观看| 少妇人妻偷人免费观看| 麻豆国产va免费精品高清在线| av高清无码 在线播放| 国产AV巨作丝袜秘书| 国产精品日韩av在线播放| 民县| 国产四虎永久免费观看| 人人澡超碰碰97碰碰碰| 女同AV在线播放| 欧美亚洲h在线一区二区| 基隆市| 中文国产不卡一区二区| 亚洲人成电影在线天堂色| 九九热免费在线观看视频| 一区二区三区成人| 欧美又黄又大又爽a片三年片| 无码人妻斩一区二区三区|