“一个都不能少”:迭代器模式

1、迭代器模式:提供一种方法顺序访问一个集合对象中各个元素,而又不暴露该对象的内部表示。
这是它的结构图:

2、迭代器模式应用场合:当需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,可以考虑使用该模式。
举个不恰当的例子,个人认为杀毒软件在遍历文件夹“排查”杀毒时可以认为是一个典型的迭代器模式的运用。因为当我们设置杀毒软件进行查杀病毒时,不管我们设置查杀文件类型为普通文件,压缩包还是隐藏的系统文件等等,杀毒软件都必须遍历这些文件进行病毒库特征匹配查杀。
3、最后,按照惯例,贴代码:
using System;
using System.Collections;
using System.Collections.Generic;

namespace IteratorPattern
{
    
/// <summary>
    
/// 迭代器抽象类
    
/// </summary>
    abstract class Iterator
    {
        
public abstract object First();
        
public abstract object Next();
        
public abstract bool IsDone();
        
public abstract object CurrentItem();
    }

    
/// <summary>
    
/// 聚集抽象类
    
/// </summary>
    abstract class Aggregate
    {
        
public abstract Iterator CreateIterator(); //创建迭代器
    }

    
/// <summary>
    
/// 具体迭代器类,这里默认将集合元素从头到尾遍历,我们可以按照需要,声明不同的具体迭代器按从尾到头遍历等等
    
/// </summary>
    class ConcreteIterator : Iterator
    {
        
private ConcreteAggregate aggregate; //具体聚集
        private int current = 0;

        
/// <summary>
        
/// 初始化时,将具体聚集传入
        
/// </summary>
        
/// <param name="aggregate"></param>
        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            
this.aggregate = aggregate;
        }

        
public override object First()
        {
            
return aggregate[0];
        }

        
public override object Next()
        {
            
object retObj = null;
            current
++;
            
if (current < aggregate.Count)
            {
                retObj 
= aggregate[current];
            }
            
return retObj;
        }

        
public override bool IsDone()
        {
            
return current >= aggregate.Count ? true : false;
        }

        
public override object CurrentItem()
        {
            
return aggregate[current]; //返回当前聚集对象
        }
    }

    
/// <summary>
    
/// 具体聚集类
    
/// </summary>
    class ConcreteAggregate : Aggregate
    {
        
//声明一个list泛型变量,用于存放集合对象,用其他集合如ArrayList同样可以实现
        private IList<object> items = new List<object>(); 
        
public override Iterator CreateIterator()
        {
            
return new ConcreteIterator(this);
        }

        
public int Count
        {
            
get { return items.Count; } //返回聚集总个数
        }

        
// 声明一个索引器
        public object this[int index]
        {
            
get { return items[index]; }
            
set { items.Insert(index, value); }
        }

    }

    
/// <summary>
    
/// 客户端调用 
    
/// </summary>
    class Program
    {
        
static void Main(string[] args)
        {
            ConcreteAggregate aggregate 
= new ConcreteAggregate(); // 把它们对应于例子中的文件夹,即具体聚集 

            aggregate[
0= "c盘system32文件夹文件"//添加要被杀毒的文件夹,即对象数组
            aggregate[1= "c盘program文件夹文件";
            aggregate[
2= "d盘游戏文件夹文件";
            aggregate[
3= "e盘所有文件";

            Iterator myIterator 
= new ConcreteIterator(aggregate); //声明迭代器对象,准备要遍历的已选中的文件夹
            object item = myIterator.First(); //取出第一个文件夹
            Console.WriteLine("第一个待查杀文件夹:{0}", item);
            
while (!myIterator.IsDone())
            {
                Console.WriteLine(
"{0} 已被查杀", myIterator.CurrentItem());
                myIterator.Next(); 
//继续往下遍历
            }

            Console.ReadLine();
        }
    }
}
ps:关于.net中的迭代器,笔者在上一篇最后一部分已经做了简要介绍,读者可自行参考。
posted on 2009-06-25 20:33  JeffWong  阅读(559)  评论(0编辑  收藏  举报