一颗不安分的创业心

DOTA版设计模式——迭代器

迭代器,将遍历集合的方法归一化,不论是ArrayList,普通数组还是其他集合类型,使得遍历集合可以统一管理。
UML图:

只要集合都实现了以下接口即可,当然接口函数可以包括Remove等方法,本例列举的是最基础的方法。
    internal interface IIterator
    {
        
bool HasNext();
        
object Next();
    }

也就是说所有的结合类可以判断是否有下一个元素,以及可以返回下一个元素。
具体的集合类代码如下:
1.ArrayList:
    internal class ArrayListIterator : IIterator
    {
        
#region IIterator 成员

        
public bool HasNext()
        {
            
if (position > arrayList.Count - 1 || arrayList[position] == null)
            {
                
return false;
            }
            
return true;
        }

        
public object Next()
        {
            
object returnValue = arrayList[position];
            position
++;
            
return returnValue;
        }

        
#endregion

        
private ArrayList arrayList;
        
private int position;

        
public ArrayListIterator(ArrayList arrayList)
        {
            
this.arrayList = arrayList;
        }
    }

2.普通数组:
    internal class ArrayIterator : IIterator
    {
        
#region IIterator 成员

        
public bool HasNext()
        {
            
if (position > array.Count - 1 || array[position] == null)
            {
                
return false;
            }
            
return true;
        }

        
public object Next()
        {
            
object returnValue = array[position];
            position
++;
            
return returnValue;
        }

        
#endregion

        
private IList array;
        
private int position;

        
public ArrayIterator(IList array)
        {
            
this.array = array;
        }
    }
在framework中已经集成了迭代器,就是我们所说的
IEnumerator接口和IEnumerable接口。
使用迭代器类型的集合时需要同一个方法CreateIterator来返回IIterator(相当于IEnumerator接口类型数据,然后可以根据返回的IIterator对象进行统一遍历,当然CreateIterator也可以定义为一个接口(IEnumerable接口)。详细见完整代码。
下面来说下我们的framework中自带的迭代器,迭代器要继承IEnumerator接口
class MyI : IEnumerator
    {

        
private ArrayList al = new ArrayList();
        
private int index = -1;
        
public MyI()
        {
            
for (int i = 0; i < 10; i++)
            {
                al.Add(i);
            }
        }

        
#region IEnumerator 成员

        
public object Current
        {
            
get { return al[index]; }
        }

        
public bool MoveNext()
        {
            
if (index < al.Count - 1)
            {
                index
++;
                
return true;
            }
            
else
            {
                
return false;
            }
        }

        
public void Reset()
        {
            index 
= -1;
        }

        
#endregion
    }
实现了IEnumerator 成员后就完成了我们的迭代器,然后就该完成生成迭代器的类了
class MyII : IEnumerable
    {
        
#region IEnumerable 成员

        
public IEnumerator GetEnumerator()
        {
            
return new MyI();
        }

        
#endregion
    }
当然我们的C#代码可以写的更优雅些,那就需要yield关键字出场了。来看下吧:
class MyIterator : IEnumerable
    {
        
private ArrayList al = new ArrayList();
        
public MyIterator()
        {
            
for (int i = 0; i < 10; i++)
            {
                al.Add(i);
            }
        }
        
#region IEnumerable 成员

        
public IEnumerator GetEnumerator()
        {
            
foreach (int tmp in al)
            {
                
yield return tmp;
            }
        }

        
#endregion
    }
代码yield return tmp;隐藏了迭代器的实现,是不是很简单那?以下是测试代码:
            MyIterator mi = new MyIterator();
            foreach (int tmp in mi)
            {
                Console.WriteLine(tmp);
            }
            MyII mi2 = new MyII();
            foreach (int tmp in mi2)
            {
                Console.WriteLine(tmp);
            }
            Console.Read();
完整代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

using DotaCommon;

namespace DotaPatternLibrary.Iterator
{
    
internal interface IIterator
    {
        
bool HasNext();
        
object Next();
    }

    
internal class ArrayListIterator : IIterator
    {
        
#region IIterator 成员

        
public bool HasNext()
        {
            
if (position > arrayList.Count - 1 || arrayList[position] == null)
            {
                
return false;
            }
            
return true;
        }

        
public object Next()
        {
            
object returnValue = arrayList[position];
            position
++;
            
return returnValue;
        }

        
#endregion

        
private ArrayList arrayList;
        
private int position;

        
public ArrayListIterator(ArrayList arrayList)
        {
            
this.arrayList = arrayList;
        }
    }

    
internal class ArrayIterator : IIterator
    {
        
#region IIterator 成员

        
public bool HasNext()
        {
            
if (position > array.Count - 1 || array[position] == null)
            {
                
return false;
            }
            
return true;
        }

        
public object Next()
        {
            
object returnValue = array[position];
            position
++;
            
return returnValue;
        }

        
#endregion

        
private IList array;
        
private int position;

        
public ArrayIterator(IList array)
        {
            
this.array = array;
        }
    }

    
internal class HeroCollection
    {
        
private ArrayList heros;
        
public HeroCollection()
        {
            heros 
= new ArrayList();
            
for (int i = 1; i <= 10; i++)
            {
                Hero hero 
= new Hero();
                hero.Name 
= "ArrayList" + i;
                heros.Add(hero);
            }
        }

        
public ArrayList GetHeros()
        {
            
return heros;
        }

        
public IIterator CreateIterator()
        {
            
return new ArrayListIterator(heros);
        }
    }

    
internal class HeroBackCollection
    {
        
private Hero[] heros = new Hero[10];
        
public HeroBackCollection()
        {
            
for (int i = 0; i < 10; i++)
            {
                Hero hero 
= new Hero();
                hero.Name 
= "Array" + i;
                heros[i] 
= hero;
            }
        }

        
public Hero[] GetHeros()
        {
            
return heros;
        }

        
public IIterator CreateIterator()
        {
            
return new ArrayIterator(heros);
        }
    }

    
internal class Hero
    {
        
private string _name;
        
public string Name
        {
            
get { return _name; }
            
set { _name = value; }
        }
    }

    
public class Game
    {
        
public void Start()
        {
            HeroCollection hcObj 
= new HeroCollection();
            IIterator heros 
= hcObj.CreateIterator();
            
while (heros.HasNext())
            {
                Hero hero 
= heros.Next() as Hero;
                LandpyForm.Form.OutputResult(hero.Name);
            }

            HeroBackCollection hbcObj 
= new HeroBackCollection();
            heros 
= hbcObj.CreateIterator();
            
while (heros.HasNext())
            {
                Hero hero 
= heros.Next() as Hero;
                LandpyForm.Form.OutputResult(hero.Name);
            }
        }
    }
}
posted @ 2009-07-26 23:02  pangxiaoliang[北京]流浪者  阅读(254)  评论(0编辑  收藏  举报
小豆芽之父