zoukankan      html  css  js  c++  java
  • [Head First设计模式]生活中学设计模式——迭代器模式

    系列文章

    [Head First设计模式]山西面馆中的设计模式——装饰者模式

    [Head First设计模式]山西面馆中的设计模式——观察者模式

    [Head First设计模式]山西面馆中的设计模式——建造者模式

    [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

    [Head First设计模式]一个人的平安夜——单例模式

    [Head First设计模式]抢票中的设计模式——代理模式

    [Head First设计模式]面向对象的3特征5原则

    [Head First设计模式]鸭子模型——策略模式

    [Head First设计模式]云南米线馆中的设计模式——模版方法模式

    [Head First设计模式]餐馆中的设计模式——命令模式

    [Head First设计模式]身边的设计模式——适配器模式

    迭代器模式

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

    类图

    角色

    Iterator:定义访问和遍历元素的接口

    Concretelterator:具体迭代器,实现迭代器接口,对该聚合遍历时跟踪当前位置。

    Aggregate:聚合,定义创建相应迭代器对象的接口。

    ConcreteAggregate:具体聚合,其工作是实现相应迭代器的接口,返回具体迭代器的一个适当的实例。

    适用场景

    1,访问一个聚合对象的内容而无需暴露它的内部表示

    2,支持对聚合对象的多种遍历

    3,为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)

    优缺点

    优点:

    1,支持以不同的方式遍历一个聚合

    2,简化了聚合的接口

    3,可同时进行多个遍历

    缺点:

    和集合密切相关,限制了其广泛使用。

    一个例子

    公共汽车售票员工作的场景:

    售票员不管上来的是人还是行李,不管是中国人还是外国人,不管是内部员工还是别的,只要是来乘车的乘客,就必须要买票。也就是说,当我们需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑用迭代模式。

    另外,售票员从车头到车尾来售票,也可以从车尾向车头来售票,也就是说,当我们需要对聚集有很多种方式遍历时,可以考虑用迭代器模式。

    由于不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个,是否结束,当前售到那一个人,这些方法每天他都在做,也就是说,当遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的过程,可以考虑使用迭代器模式。

     这里使用IEnumerator,.net中的迭代器接口

     1 namespace System.Collections
     2 {
     3     // 摘要: 
     4     //     支持对非泛型集合的简单迭代。
     5     [ComVisible(true)]
     6     [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
     7     public interface IEnumerator
     8     {
     9         // 摘要: 
    10         //     获取集合中的当前元素。
    11         //
    12         // 返回结果: 
    13         //     集合中的当前元素。
    14         object Current { get; }
    15 
    16         // 摘要: 
    17         //     将枚举数推进到集合的下一个元素。
    18         //
    19         // 返回结果: 
    20         //     如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
    21         //
    22         // 异常: 
    23         //   System.InvalidOperationException:
    24         //     在创建了枚举数后集合被修改了。
    25         bool MoveNext();
    26         //
    27         // 摘要: 
    28         //     将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
    29         //
    30         // 异常: 
    31         //   System.InvalidOperationException:
    32         //     在创建了枚举数后集合被修改了。
    33         void Reset();
    34     }
    35 }

    Concretelterator:具体迭代器,实现迭代器接口,对该聚合遍历时跟踪当前位置。

     1 namespace Wolfy.迭代器模式
     2 {
     3     public class Concretelterator : IEnumerator
     4     {
     5         private ConcreteAggregate aggregate;
     6        private  int currentIndex=-1;
     7         public Concretelterator(ConcreteAggregate aggregate)
     8         {
     9             this.aggregate = aggregate;
    10         }
    11         public object Current
    12         {
    13             get { return aggregate[currentIndex]; }
    14         }
    15 
    16         public bool MoveNext()
    17         {
    18             currentIndex++;
    19             return currentIndex < this.aggregate.Count;
    20            
    21         }
    22 
    23         public void Reset()
    24         {
    25             currentIndex = -1;
    26         }
    27     }
    28 }
    1 namespace Wolfy.迭代器模式
    2 {
    3     public abstract class Aggregate
    4     {
    5         public abstract IEnumerator CreateEnumerator();
    6     }
    7 }

    ConcreteAggregate:具体聚合,其工作是实现相应迭代器的接口,返回具体迭代器的一个适当的实例。

     1 namespace Wolfy.迭代器模式
     2 {
     3     public class ConcreteAggregate : Aggregate
     4     {
     5         private  ArrayList arr=new ArrayList();
     6         public int Count
     7         {
     8             get { return arr.Count; }
     9         }
    10         public object this[int index]
    11         {
    12             get { return arr[index]; }
    13             set { arr.Insert(index, value); }
    14         }
    15         public override System.Collections.IEnumerator CreateEnumerator()
    16         {
    17             return new Concretelterator(this);
    18         }
    19     }
    20 }

    测试

     1 namespace Wolfy.迭代器模式
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7 
     8             ConcreteAggregate agg = new ConcreteAggregate();
     9             agg[0] = "乘客1";
    10             agg[1] = "乘客2";
    11             agg[2] = "乘客3";
    12             agg[3] = "乘客4";
    13             agg[4] = "乘客5";
    14             agg[5] = "乘客6";
    15             agg[6] = "乘客7";
    16             agg[7] = "乘客8";
    17             agg[8] = "乘客9";
    18             agg[9] = "乘客10";
    19             IEnumerator iterator =agg.CreateEnumerator();
    20             while (iterator.MoveNext())
    21             {
    22                 Console.WriteLine(iterator.Current);
    23             }
    24             iterator.Reset();
    25             Console.Read();
    26         }
    27     }
    28 }

    结果:

    总结

    这个模式给你提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。

    参考书:

    《Head First 设计模式》

  • 相关阅读:
    Caffe proto閱讀
    C++ 基本知識回顧
    Caffe 源碼閱讀(二) SyncedMemory.hpp
    Caffe 源碼閱讀(一) Blob.hpp
    Matlab
    python
    MxNet下训练alexnet(一)
    服务器自己用户名下编译gcc
    Using python to process Big Data
    23 October
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/3633600.html
Copyright © 2011-2022 走看看