C#设计模式系列:迭代器模式(Iterator)
迭代器模式把对象的职责分离,职责分离可以最大限度减少彼此之间的耦合程度,从而建立一个松耦合的对象。职责分离的要点是对被分离的职责进行封装,并以抽象的方式建立彼此之间的关系。
1、迭代器模式简介
1.1>、定义
迭代器模式提供一种方法可以顺序访问聚合对象中各个元素,但又不暴露该对象的内部表示。
1.2>、使用频率
高
2、迭代器模式结构
2.1>、结构图
2.2>、参与者
迭代器模式参与者:
◊ Iterator:迭代器定义访问和遍历元素的接口
◊ ConcreteIterator
° 具体迭代器实现迭代器接口
° 对该聚合遍历时跟踪当前位置
◊ Aggregate:聚合定义创建Iterator对象的接口
◊ ConcreteAggregate:具体聚合,实现相应迭代器的接口,返回具体迭代器的一个适当的实例。
在迭代器模式中,ConcreteAggregate通过Aggregate定义的接口得到Iterator,并且这是一个ConcreteIterator,该ConcreteIterator具体实现了对ConcreteAggregate的访问与遍历的方法。通过ConcreteIterator可以访问并使用集合中的元素。
3、迭代器模式结构实现
Iterator.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Structural
- {
- public abstract class Iterator
- {
- public abstract object First();
- public abstract object Next();
- public abstract bool IsDone();
- public abstract object CurrentItem();
- }
- }
Aggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Structural
- {
- public abstract class Aggregate
- {
- public abstract Iterator CreateIterator();
- }
- }
ConcreteAggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Collections;
- namespace DesignPatterns.IteratorPattern.Structural
- {
- public class ConcreteAggregate : Aggregate
- {
- private ArrayList _items = new ArrayList();
- 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); }
- }
- }
- }
ConcreteIterator.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Structural
- {
- public class ConcreteIterator : Iterator
- {
- private ConcreteAggregate _aggregate;
- private int _current = ;
- public ConcreteIterator(ConcreteAggregate aggregate)
- {
- this._aggregate = aggregate;
- }
- public override object First()
- {
- return _aggregate[];
- }
- public override object Next()
- {
- object ret = null;
- if (_current < _aggregate.Count - )
- {
- ret = _aggregate[++_current];
- }
- return ret;
- }
- public override object CurrentItem()
- {
- return _aggregate[_current];
- }
- public override bool IsDone()
- {
- return _current >= _aggregate.Count;
- }
- }
- }
Program.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DesignPatterns.IteratorPattern.Structural;
- namespace DesignPatterns.IteratorPattern
- {
- class Program
- {
- static void Main(string[] args)
- {
- ConcreteAggregate a = new ConcreteAggregate();
- a[] = "Item A";
- a[] = "Item B";
- a[] = "Item C";
- a[] = "Item D";
- ConcreteIterator i = new ConcreteIterator(a);
- Console.WriteLine("Iterating over collection:");
- object item = i.First();
- while (item != null)
- {
- Console.WriteLine(item);
- item = i.Next();
- }
- }
- }
- }
运行输出:
- Iterating over collection:
- Item A
- Item B
- Item C
- Item D
- 请按任意键继续. . .
4、迭代器模式实践应用
在迭代器模式的设计中,有两种具体的实现方式,分别为外禀迭代器和内禀迭代器。白箱聚集与外禀迭代器:白箱聚集向外界提供访问自己内部元素的接口,从而使得外禀迭代器可以通过聚集提供的方法实现迭代功能。黑箱聚集与内禀迭代器:黑箱聚集不向外界提供遍历自己内部元素的接口,因此聚集的成员只能被聚集内部的方法访问。由于内禀迭代器恰好也是聚集的成员,因此可以访问聚集元素。
4.1、外禀迭代器
外禀迭代器的迭代过程使用了集合中的元素,通过集合向外界提供了访问自身内部元素的机会。
Iterator.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.ExtrinsicIterator
- {
- /// <summary>
- /// 定义一个迭代器接口
- /// </summary>
- public interface Iterator
- {
- /// <summary>
- /// 迭代器定位到聚合的第一个元素
- /// </summary>
- void First();
- /// <summary>
- /// 遍历下一个
- /// </summary>
- void Next();
- /// <summary>
- /// 判断是否完成遍历
- /// </summary>
- /// <returns></returns>
- bool IsDone();
- /// <summary>
- /// 获得当前遍历的项
- /// </summary>
- /// <returns></returns>
- object CurrentItem();
- }
- }
ConcreteIterator.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.ExtrinsicIterator
- {
- /// <summary>
- /// 定义具体的迭代器类
- /// </summary>
- public class ConcreteIterator : Iterator
- {
- private ConcreteAggregate aggregate;
- private int index = ;
- private int size = ;
- /// <summary>
- /// 根据不同的聚合类进行初始化
- /// </summary>
- /// <param name="aggregate"></param>
- public ConcreteIterator(ConcreteAggregate aggregate)
- {
- this.aggregate = aggregate;
- size = aggregate.Size();
- index = ;
- }
- public void First()
- {
- index = ;
- }
- public void Next()
- {
- if (index < size)
- {
- index++;
- }
- }
- /// <summary>
- /// 判断是否遍历完毕
- /// </summary>
- /// <returns></returns>
- public bool IsDone()
- {
- return index >= size;
- }
- /// <summary>
- /// 获取当前遍历的元素
- /// </summary>
- /// <returns></returns>
- public object CurrentItem()
- {
- return aggregate.GetElement(index);
- }
- }
- }
Aggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.ExtrinsicIterator
- {
- /// <summary>
- /// 定义一个抽象的聚合类
- /// </summary>
- public abstract class Aggregate
- {
- /// <summary>
- /// 只有一个功能,创建迭代器
- /// </summary>
- /// <returns></returns>
- public virtual Iterator CreateIterator()
- {
- return null;
- }
- }
- }
ConcreteAggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.ExtrinsicIterator
- {
- /// <summary>
- /// 定义一个具体的聚合类
- /// </summary>
- public class ConcreteAggregate : Aggregate
- {
- // 存储元素的集合
- private object[] objs = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
- /// <summary>
- /// 获得元素个数
- /// </summary>
- /// <returns></returns>
- public int Size()
- {
- return objs.Length;
- }
- /// <summary>
- /// 获取指定序号的元素
- /// </summary>
- /// <param name="index">指定的序号</param>
- /// <returns></returns>
- public object GetElement(int index)
- {
- if (index < || index > objs.Length)
- {
- return null;
- }
- return objs[index];
- }
- /// <summary>
- /// 创建该聚合类的迭代器
- /// </summary>
- /// <returns></returns>
- public override Iterator CreateIterator()
- {
- return new ConcreteIterator(this);
- }
- }
- }
Client.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.ExtrinsicIterator
- {
- public class Client
- {
- private Iterator _iterator;
- private Aggregate _aggregate = new ConcreteAggregate();
- public void Operation()
- {
- // 获得迭代器
- _iterator = _aggregate.CreateIterator();
- while (!_iterator.IsDone())
- {
- Console.WriteLine(_iterator.CurrentItem());
- _iterator.Next();
- }
- }
- static void Main(string[] args)
- {
- Client client = new Client();
- client.Operation();
- }
- }
- }
运行输出:
- Sunday
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
- 请按任意键继续. . .
4.2、内禀迭代器
内禀迭代器实现的关键是在集合的内部定义一个私有的具体迭代子类,由它来负责迭代器的所有功能。因为它是集合的私有类,所以它的对象可以遍历集合的内部元素,实现迭代器定义的所有接口,而集合本身并未向外界提供访问自己内部元素的接口。
Iterator.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.IntrinsicIterator
- {
- /// <summary>
- /// 定义一个迭代器接口
- /// </summary>
- public interface Iterator
- {
- /// <summary>
- /// 迭代器定位到聚合的第一个元素
- /// </summary>
- void First();
- /// <summary>
- /// 遍历下一个
- /// </summary>
- void Next();
- /// <summary>
- /// 判断是否完成遍历
- /// </summary>
- /// <returns></returns>
- bool IsDone();
- /// <summary>
- /// 获得当前遍历的项
- /// </summary>
- /// <returns></returns>
- object CurrentItem();
- }
- }
Aggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.IntrinsicIterator
- {
- /// <summary>
- /// 定义一个抽象的聚合类
- /// </summary>
- public abstract class Aggregate
- {
- /// <summary>
- /// 只有一个功能,创建迭代器
- /// </summary>
- /// <returns></returns>
- public virtual Iterator CreateIterator()
- {
- return null;
- }
- }
- }
ConcreteAggregate.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.IntrinsicIterator
- {
- /// <summary>
- /// 定义一个具体的聚合类
- /// </summary>
- public class ConcreteAggregate : Aggregate
- {
- // 存储元素的集合
- private static object[] objs = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
- /// <summary>
- /// 定义具体的迭代器类
- /// </summary>
- private class ConcreteIterator : Iterator
- {
- private int _index = ;
- public void First()
- {
- _index = ;
- }
- public void Next()
- {
- if (_index < objs.Length)
- {
- _index++;
- }
- }
- public bool IsDone()
- {
- return _index == objs.Length;
- }
- public object CurrentItem()
- {
- return objs[_index];
- }
- }
- /// <summary>
- /// 获得元素个数
- /// </summary>
- /// <returns></returns>
- public int Size()
- {
- return objs.Length;
- }
- /// <summary>
- /// 获取指定序号的元素
- /// </summary>
- /// <param name="index">指定的序号</param>
- /// <returns></returns>
- public object GetElement(int index)
- {
- if (index < || index > objs.Length)
- {
- return null;
- }
- return objs[index];
- }
- /// <summary>
- /// 创建该聚合类的迭代器
- /// </summary>
- /// <returns></returns>
- public override Iterator CreateIterator()
- {
- return new ConcreteIterator();
- }
- }
- }
Client.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace DesignPatterns.IteratorPattern.Practical.IntrinsicIterator
- {
- public class Client
- {
- private Iterator _iterator;
- private Aggregate _aggregate = new ConcreteAggregate();
- public void Operation()
- {
- // 获得迭代器
- _iterator = _aggregate.CreateIterator();
- while (!_iterator.IsDone())
- {
- Console.WriteLine(_iterator.CurrentItem());
- _iterator.Next();
- }
- }
- static void Main(string[] args)
- {
- Client client = new Client();
- client.Operation();
- }
- }
- }
5、迭代器模式应用分析
迭代器模式适用情形:
1>、访问一个具体对象的内容而不暴露它的内部表示;
2>、支持对聚合对象的多种遍历;
3>、为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)。
迭代器模式特点:
1>、简化聚集的行为,迭代器具备了遍历的接口,这样聚集的接口就不必具备遍历接口;
2>、每一个聚集对象都可以有一个或者更多的迭代器对象,每一个迭代器的迭代状态可以彼此独立(外禀迭代器);
3>、遍历算法被封装到迭代器对象中,迭代算法可以独立于聚集对象变化。Client不必知道聚集对象的类型,通过迭代器可以就读取和遍历聚集对象。这样的好处是聚集本身内部数据发生变化而不影响Client的程序。
C#设计模式系列:迭代器模式(Iterator)的更多相关文章
- 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...
- 二十四种设计模式:迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...
- [设计模式] 16 迭代器模式 Iterator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...
- 设计模式之迭代器模式(Iterator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式 笔记 迭代器模式 Iterator
//---------------------------15/04/26---------------------------- //Iterator 迭代器模式----对象行为型模式 /* 1:意 ...
- 行为型设计模式之迭代器模式(Iterator)
结构 意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示. 适用性 访问一个聚合对象的内容而无需暴露它的内部表示. 支持对聚合对象的多种遍历. 为遍历不同的聚合结构提供一 ...
- 设计模式之迭代器模式 Iterator
代码实现 public interface MyIterator { void first(); //将游标指向第一个元素 void next(); //将游标指向下一个元素 boolean hasN ...
- Java 设计模式系列(十五)迭代器模式(Iterator)
Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...
- 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素
模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...
随机推荐
- JDBC
<java连接数据库> Class.forName("com.mysql.jdbc.Driver")--1:加载驱动 Connection conn=DriverMan ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- 阿里云ECS(Centos)开启X11的步骤
阿里云ECS(Centos)开启X11的步骤 1.修改sshd_config X11Forwarding yes 2.yum -y install xorg-x11-xauth xorg-x11-ut ...
- 来自XP的道别信
当你们看到这封信的时候,很抱歉要和大家说再见了! 亲爱的你们,对不起,请不要为我哭泣,请让我们一起度过这最后的时光. 请记住那个在蓝天白云下奔跑的我!
- Spark优化之三:Kryo序列化
Spark默认采用Java的序列化器,这里建议采用Kryo序列化提高性能.实测性能最高甚至提高一倍. Spark之所以不默认使用Kryo序列化,可能的原因是需要对类进行注册. Java程序中注册很简单 ...
- centos 7.2 安装PHP7.1+apache2.4.23
安装准备: http://ftp.cuhk.edu.hk/pub/packages/apache.org//httpd/httpd-2.4.23.tar.gz 下载apache http://cn ...
- java实现PDF转HTML
问题场景: 在使用PB嵌入HTML页面时发现调不起查看PDF的插件 解决方法: 将PDF转换为HTML来展示 解决步骤: 1.下载PDF转换工具.exe 下载地址:http://pan.baidu.c ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
- 360急速浏览器BUG,POST表单提交参数丢失
p{text-indent:2em;} --> 今天我在做支付宝充值的时候发现在360急速浏览器下面业务处理页面获取Request.Form参数为空,一开始我还以为是自己参数没有传递过去.然后就 ...
- canvas :曲线的面积图 加渐变效果
document.body.innerHTML = '<canvas></canvas>' var cvs = document.querySelector("can ...