• 设计模式Iterator Pattern迭代者模式


    所谓迭代者模式就是:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。[GOF 《设计模式》] 
      在软件的构建过程中,集合对象(也就是聚集:是一组数据集或者对象集,它可以通过循环来访问 )内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也 为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种比较好 的方式。
      我们在平时的开发中经常直接或间接地使用到此模式,我们使用foreach语句来循环就是在间接的使用C# Iterator迭代器模式。
      迭代器就像指针一样可以向前向后移动,在.NET中迭代器只能向后移动。
      此模式的UML图如下:

                            

      由图可知,它有以下角色

         1、Aggregate 接口: 抽象的聚集,通常只留有一个方法让子类去实现,这个方法的作用是获得一个枚举器对象,通常可以起名字为 GetIterator( ),CreateIterator( ) 等等,或者干脆叫做 Iterator( ) 也行。在 C# 中,这个方法的名字叫做 GetEnumerator( ) ,这个我们到后面再讲。当然,在获得枚举器的同时,也要把自己 this(一组数据集)当作参数传给枚举器,想想也是,如果没有数据集,枚举器去枚举什么呢?
         2、ConcreteAggregate 类: 具体的聚集,它的实例保存了一组数据集,同时它实现了 Aggregate 接口中唯一的那个方法,通常情况下他也会扩展出一些其他方法便于访问聚集中的数据,常见的有:访问某个位置数据的方法,可以叫做 GetElement(int index) 或者 GetItem(int index) 等等;获得聚集大小的方法,可以起名字为 GetLength( ) 或者 GetSize( ) 等等,全看自己喜好。我们这里叫Count。
         3、Iterator 接口: 抽象的枚举器,通常情况下会有三个方法留给子类去实现,他们分别是:Next( ) ,用来把指针移动到聚集中的下一个数据;HasNext( ) ,用来判断是否还有下一个数据;CurrentItem( ),返回当前指针所指位置的数据。也可以把 Next( ) 和 CurrentItem( ) 组成一个方法,在移动指针的同时返回一个数据。也可以有其他的实现方式,或者简单,或者复杂,也是全看个人需求。
         4、ConcreteIterator 类:具体的枚举器,它实现了上述的三个方法,通过不同的实现方式,我们可以获得不同的枚举方式,如顺序枚举、倒序枚举等等。当然,这个类的构造方法中会接受一个具体聚集参数,想想也是,如果没有这个数据集,他去枚举什么呢?这个参数就是他要去枚举的对象。
         5、被聚集的类,这个可以是任何类,它的许多个对象被存到聚集对象中才能形成一个真正的聚集。
       下面,我们用两段代码来示例此模式。
       程序如下图:   
                            
      一、迭代者模式运基本思想示例
       1、Aggregate 接口:Aggregate.


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    #region 定义Aggregate抽象类
        
    //实现迭代接口,返回迭代器  
        abstract  class Aggregate
        {
            
    ////在这里进行解藕,将集合对象转换为迭代器  
            public abstract Iterator CreateIterator();
        }
        
    #endregion
    }

       2、ConcreteAggregate 类:


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;

    namespace MyIterator
    {
        
    //定义ConcreteAggregate类,它继承自Aggregate
        class ConcreteAggregate:Aggregate 
        {
            
    private ArrayList _items = new ArrayList();
            
    #region 实现基类Aggregate定义的操作CreateIterator
            
    public override Iterator CreateIterator()
            {
                
    //因为在ConcreteIterator构造函数中需要传入ConcreteAggregate类的实例
                
    //所以在此处实现CreateIterator功能时ConcreteAggregate类实例作为参数传入
                
    //从而在ConcreteAggregate与CreateIterator之间建立了联系
                return new ConcreteIterator(this);
            }
            
    #endregion

            
    #region 得到Item的数目
            
    public int Count
            {
                
    get { return _items.Count; }
            }
            
    #endregion

            
    #region 获取指定位置的元素
            
    public object this[int index]
            {
                
    get { return _items[index]; }
                
    set { _items.Insert(index, value); }
            }
            
    #endregion
        }
    }

       3、Iterator 接口


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    #region 定义Interator接口
        
    //此处定义了Interator子类需要实现的遍历操作
        public  abstract class Iterator
        {
            
    public abstract object First();
            
    public abstract object Next();
            
    public abstract bool IsDone();
            
    public abstract object CurrentItem();
        }
        
    #endregion
    }

       4、ConcreteIterator 类:


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    #region 定义ConcreteInterator类
             
    //此类继承自Interator类,实现了迭代器接口  
            
    //First();  Next(); IsDone();CurrentItem();
        class ConcreteIterator:Iterator 
        {
            
    private ConcreteAggregate _aggregate;
            
    private int _current = 0;

            
    #region 构造函数
            
    //构造时引入集合实例aggregate,从而将集合类型转换成内部成员  
            
    //我们通过ConcreteIterator方法,将集合对象转换为了可迭代对象,这实际上是在对集合对象进行抽象,将他转换为迭代器
            public ConcreteIterator(ConcreteAggregate aggregate)
            {
                
    this._aggregate = aggregate;
            }
            
    #endregion

            
    #region 得到第一个元素
            
    public override object First()
            {
                
    return _aggregate[0];
            }
            
    #endregion

            
    #region 得到当前元素的下一个元素
            
    public override object Next()
            {
                
    object retObject = null;
                
    if( _current<_aggregate.Count-1 )
                {
                    
    //如果当前项后面还有元素则取得下一个元素并返回
                    retObject = _aggregate[++_current];
                }
                
    return retObject;
            }

            
    #endregion

            
    #region 取得当前项元素
            
    public override object CurrentItem()
            {
                
    return _aggregate[_current];
            }

            
    #endregion

            
    #region 是否遍历完所有元素
            
    public override bool IsDone()
            {
                
    return _current >= _aggregate.Count;
            }

            
    #endregion
        }
        
    #endregion
    }

       5、被聚集的类,此处我们用字符串来实现
      6、客户端应用


                #region 运作思想示例
                
    //定义一个集合对象并初始化
                ConcreteAggregate ca = new ConcreteAggregate();
                
    for (int i = 0; i < 8; i++)
                {
                    ca[i] 
    = "Item " + (i + 1).ToString();
                }

                
    //创建一个迭代器,并传入上面创建的集合对象
                ConcreteIterator ci = new ConcreteIterator(ca);
                Console.WriteLine(
    "--------------遍历集合对象-----------");

                
    object item = ci.First();
                
    while (item != null)
                {
                    Console.WriteLine(item);
                    item 
    = ci.Next();
                }

                Console.ReadKey();
                
    #endregion

     

      二、以士兵作为被聚集的类来示例实现
       1、Aggregate 接口:IAbstractCollection接口


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;

    namespace MyIterator
    {
        
    #region IAbstractCollection接口
        
    interface  IAbstractCollection
        {
            
            SoldierIterator CreateIterator();
        }
        
    #endregion
    }

       2、ConcreteAggregate 类: SoldierCollection类


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;

    namespace MyIterator
    {
        
    class SoldierCollection:IAbstractCollection 
        {
           
            
    private ArrayList _item = new ArrayList();

            
    //返回迭代器  
            public SoldierIterator CreateIterator()
            {
                
    return new SoldierIterator(this);
            }

            
    #region 获取当前集合对象的元素数目
            
    public int Count
            {
                
    get { return _item.Count;}
            }
            
    #endregion

            
    #region 获取指定位置的元素
            
    public object this[int index]
            {
                
    get { return _item[index]; }
                
    set { _item.Add(value); }
            }

            
    #endregion
        }
    }

       3、Iterator 接口: IAbstractIterator接口


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    #region  
        
    interface IAbstractIterator
        {
            
    //要求实现First,Next,IsDone与CurrentItem功能
            Soldier First();
            Soldier Next();
            
    bool IsDone{get;}
            Soldier CurrentItem {
    get; }
        }
        
    #endregion
    }

       4、ConcreteIterator 类:SoldierIterator类


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    class SoldierIterator:IAbstractIterator 
        {
            
    private SoldierCollection _collection;
            
    private int _current = 0;
            
    private int _step = 1;
            
    #region 构造函数
            
    public SoldierIterator(SoldierCollection collection)
            {
                
    this._collection = collection;
            }
            
    #endregion

            
    #region 得到队列中的第一名士兵
            
    public Soldier First()
            {
                _current 
    = 0;
                
    return _collection[_current] as Soldier;
            }

            
    #endregion

            
    #region 得到下一名士兵
            
    public Soldier Next()
            {
                _current 
    += _step;
                
    if (!IsDone)
                {
                    
    return _collection[_current] as Soldier;
                }
                
    else
                {
                    
    return null;
                }

            }
            
    #endregion

            
    #region 获取或设置前进步伐
            
    public int Step
            {
                
    get { return _step; }
                
    set { _step = value; }
            }
            
    #endregion

            
    #region 获取当前士兵
            
    public Soldier CurrentItem
            {
                
    get { return _collection[_current] as Soldier; }
            }
            
    #endregion

            
    #region 判断是否遍历完成
            
    public bool IsDone
            {
                
    get { return _current >= _collection.Count; }
            }
            
    #endregion



        }
    }

       5、被聚集的类:Soldier


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MyIterator
    {
        
    class Soldier
        {
            
    #region Name属性
            
    private string _name;
            
    public string Name
            {
                
    get { return _name; }
            }
            
    #endregion

            
    #region 构造函数
            
    public Soldier(string name)
            {
                
    this._name = name;
            }
            
    #endregion


        }
    }

      6、客户端应用 


                #region 我的团长我的团
                SoldierCollection collection 
    = new SoldierCollection();
                collection[
    0= new Soldier("孟烦了");
                collection[
    1= new Soldier("不辣");
                collection[
    2= new Soldier("迷龙");
                collection[
    3= new Soldier("豆饼");
                collection[
    4= new Soldier("要麻");
                collection[
    5= new Soldier("蛇屁股");
                collection[
    6= new Soldier("康丫");
                collection[
    7= new Soldier("郝兽医");
                collection[
    8= new Soldier("阿译");

                SoldierIterator si 
    = new SoldierIterator(collection);

                
    //设置指针前移距离
                si.Step = 1;
                
    //按指定步距遍历一次
                Console.WriteLine("--------我的团长我的团----------");

                
    //Soldier sd = si.First();
                
    //while(sd!=null)
                
    //{
                
    //    Console.WriteLine(sd.Name);
                
    //    sd=si.Next();
                
    //}

                
    for (Soldier sd = si.First(); !si.IsDone; sd = si.Next())
                {
                    Console.WriteLine(sd.Name);
                }
                Console.ReadKey();

                
    #endregion

      运行效果如下:
                              


     

    前往:设计模式学习笔记清单
  • 相关阅读:
    getSupportFragmentManager要用在FragmentActivity及其子类中
    nginx 配置php
    openwrt 安装 ser2net 配置
    stm32 hid 键盘描述
    外部中断实验
    stm32 UART串口
    stm32 按键
    小结-stm32 驱动LED灯
    ASCII 计算机码
    debian/ubuntu安装桌面环境
  • 原文地址:https://www.cnblogs.com/smallfa/p/1602902.html
Copyright © 2020-2023  润新知