四.行为型——迭代器模式

0.《设计模式》摘录

  • 意图:
      一个聚合对象需要能够被遍历其中的元素,同时又不暴露它的内部结构。

  • 多态迭代:
      为遍历不同的聚合结构提供一个统一的接口
     为所有的列表定义一个公共的操作接口AbstractList
     为所有的迭代器类定义一个公共的接口Iterator
     为每种具体的列表定义具体的迭代器,由列表对象负责创建相应的迭代器
     可以在列表类中定义相应的工厂方法创建对应的迭代器
     下面结构图就是多态迭代

  • 适用性:
    访问一个聚合对象的内容而无需暴露它的内部表示
    支持对同一聚合对象的多种遍历
    为遍历不同的聚合结构提供一个统一的接口(多态迭代)

  • 实现:

    • 谁定义迭代算法:【下面的例子是外部迭代器】
        关键的区别在于推动遍历的循环是在迭代器内部还是外部定义
       外部迭代器:由使用迭代器的客户控制迭代过程,客户需要主动推进遍历的步骤,显式地向迭代器请求下一元素。
        内部迭代器:客户向迭代器提交一个待执行的操作,迭代器将自动完成对聚合中元素的遍历并对每个元素实施这个操作。

    • 谁定义遍历算法:
      在迭代器中定义:
       易于在相同的聚合上使用不同的迭代算法
       改变迭代器即可
       也易于在不同的聚合上重用相同的算法
       同样的迭代器(例如同样的过滤标准)用在不同的聚合上
        但如果遍历算法需要访问聚合对象的私有变量,这种方式会破坏聚合的封装性。
       
      在聚合中定义:
       在遍历过程中迭代器存储当前迭代的状态,这种迭代器称为游标,客户程序以游标为参数调用聚合的Next操作得到下一元素, Next操作同时修改游标的状态。
       注意这里Next是聚合对象的方法

迭代器模式

  • 定义

    迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

  • 结构图

    在这里插入图片描述

    • Iterator迭代器抽象类:提供统一的接口

      abstract class Iterator
      {
          public abstract Object First();//注意返回的是Object
          public abstract Object Next();
          public abstract Object IsDone();
          public abstract Object CurrentItem();
      }
      
    • Concreteiterator:具体迭代器类,继承 Iterator

      class ConcreteIterator extends Iterator
      {
          private ConcreteAggregate aggregate;
          private int current = 0;
          public Concreteiterator(ConcreteAggregate aggregate)
          {
              this.aggregate = aggregate;
          }
      
          public override object Next()
          {
              object ret = null; 
              current++;
              if (current < aggregate.Count) 
              {
                  ret = aggregate[current];
              } 
              return ret;
          }
      
      
          public override bool IsDone()
          {
              return current >= aggregate.Count ? true : false;
          }
      
          public override object Currentitem()
          {
              return aggregate[current];
          }
      }
      
    • Aggregate聚集抽象类:创建迭代器

      abstract Class Aggregate
      {
          public abstract Iterator CreateIterator ();
      }
      
    • ConcreteAggregate :具体聚集类,继承 Aggregate

      class ConcreteAggregate extends Aggregate
      {
          //声明一个List泛型变量,用于存放聚合对象
          private List<object> items = new List<object>();
      
          public override Iterator CreateIterator()
          {
              return new Concreteiterator(this);
          }	
      
          //返回聚集总个数
          public int getCount()
          {
              return items.count();
          }
      
          //声明一个索引器
          public object this[int index]
          {
              get ( return items[index]); 
              set ( items.Insert(index, value)); 
          }
      }
      
    • 客户端代码

      static void Main(string[] args)
      {
          ConcreteAggregate a = new ConcreteAggregate();
          a[0]="大鸟";
          a[1]="小菜";
          a[2]="行李";
          a[3]="老外";
          a[4]="公交内部员工";
          a[5]="小偷";
      
          Iterator i = new Concreteiterator(a);
          object item = i.First();
          while (!i.IsDone())
          {
              Console .WriteLine (" {0}请买车票!", i .Currentitem ()); 
              i.Next ();
          }
          Console.Read ();
      }
      

    运行结果:
    大鸟请买车票

    小菜请买车票

    行李请买车票

    老外请买车票

    公交内部员工请买车栗

    小偷请买车票

  • 优点

    迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

  • 什么时候用迭代器模式?

    1. 当你需要访问一个聚集对象,而且不管这些対象是什么都需要遍历的时候。

      举例:售票员不管你上来的谁,只要是来乘车的乘客,就必须要买票。

    2. 需要对聚集对象有多种方式遍历时

      举例:售票员从车头到车尾来售票,也可以从车尾向车头来售票

    3. 遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口

      比如:不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个是谁,是否结束,当前售到哪个人了,他每天都在做统一的操作。

  • 为什么需要一个迭代器的抽象类,而不是只要具体类?

    因为可以通过继承,实现对聚集多种方式遍历。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值