C#设计模式之16-迭代器模式
迭代器模式(Iterator Pattern)
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/417 访问。
迭代器模式属于行为型模式,它提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
角色:
1、迭代器(Iterator)
迭代器角色负责定义访问和遍历元素的接口;
2、具体迭代器(Concrete Iteraror)
具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置;
3、聚合(Aggregate)
聚合角色负责定义获得迭代器角色的接口;
4、具体聚合(Concrete Aggregate)
具体聚合角色实现聚合角色接口。
示例:
命名空间IteratorPattern中包含Person基类、People类、PelpleEnum类,另外包含一个苹果手机ApplePhone类,和BestEnum类。Person示例来自微软官方的IEnumerable接口介绍页面,BestEnum则使用.Net 2.0中的yield return关键字创建苹果手机信息序列。
namespace IteratorPattern
一、传统迭代器实现
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName) {
this.FirstName = firstName;
this.LastName = lastName;
}
}
Person类,包含First Name和Last Name。
public class People : IEnumerable {
private Person[] _people = null;
public People(Person[] pArray) {
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++) {
_people[i] = pArray[i];
}
}
public IEnumerator GetEnumerator() {
return new PeopleEnum(_people);
}
}
People类,实现IEnumerable接口。
public class PeopleEnum : IEnumerator {
private Person[] _people = null;
private int _cursor = -1;
public PeopleEnum(Person[] list) {
_people = list;
}
public bool MoveNext() {
_cursor++;
return (_cursor < _people.Length);
}
public void Reset() {
_cursor = -1;
}
public object Current {
get {
try {
return _people[_cursor];
}
catch (IndexOutOfRangeException) {
throw new InvalidOperationException();
}
}
}
}
PeopleEnum类,实现IEnumerator接口。
二、yield return迭代器实现
yield关键字向编译器指示它所在的方法是迭代器块,yield return返回一个迭代器的状态机。
C#开发笔记之05-迭代器中的状态机(State Machine)到底是什么?
public class ApplePhone {
public string PhoneName { get; set; }
public DateTime PublishedDate { get; set; }
}
ApplePhone类,包含手机名称和发布日期。
public class BestEnum {
public static IEnumerable<ApplePhone> GetIPhones() {
yield return new ApplePhone {
PhoneName = "IPhone",
PublishedDate = new DateTime(2007, 1, 9)
};
yield return new ApplePhone {
PhoneName = "IPhone 3G",
PublishedDate = new DateTime(2008, 6, 10)
};
yield return new ApplePhone {
PhoneName = "IPhone 3GS",
PublishedDate = new DateTime(2009, 6, 9)
};
yield return new ApplePhone {
PhoneName = "IPhone 4",
PublishedDate = new DateTime(2010, 6, 8)
};
//部分代码已省略
}
}
BestEnum类,包含GetIPhones方法返回苹果手机信息的序列。
public class Program {
protected const string LINE_BREAK =
"---------------------------------------------";
public static void Main(string[] args) {
var peopleArray = new Person[]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon")
};
var peopleList = new People(peopleArray);
foreach(Person p in peopleList)
Console.WriteLine(p.FirstName + " " + p.LastName);
Console.WriteLine(LINE_BREAK);
var iterator = peopleList.GetEnumerator();
while(iterator.MoveNext()) {
var person = iterator.Current as Person;
Console.WriteLine(person.FirstName + " " + person.LastName);
}
Console.WriteLine(LINE_BREAK);
foreach(var phone in BestEnum.GetIPhones()) {
Console.WriteLine("[" + phone.PhoneName + "] was released in " +
phone.PublishedDate.ToString("yyyy-MM-dd") + "!");
}
Console.WriteLine(LINE_BREAK);
Console.ReadKey();
}
}
以上是调用方的代码,以下是这个案例的输出结果:
John Smith
Jim Johnson
Sue Rabon
---------------------------------------------
John Smith
Jim Johnson
Sue Rabon
---------------------------------------------
[IPhone] was released in 2007-01-09!
[IPhone 3G] was released in 2008-06-10!
[IPhone 3GS] was released in 2009-06-09!
[IPhone 4] was released in 2010-06-08!
[IPhone 4s] was released in 2011-10-04!
[IPhone 5] was released in 2012-09-13!
[IPhone 5S] was released in 2013-09-10!
[IPhone 5C] was released in 2013-09-10!
[IPhone 6] was released in 2014-09-10!
[IPhone 6 Plus] was released in 2014-09-10!
[IPhone 6s] was released in 2015-09-10!
[IPhone 6s Plus] was released in 2015-09-10!
[IPhone 7] was released in 2016-09-08!
[IPhone 7 Plus] was released in 2016-09-08!
[IPhone 8] was released in 2017-09-13!
[IPhone 8 Plus] was released in 2017-09-13!
[IPhone X] was released in 2017-09-13!
---------------------------------------------
优点:
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/417 访问。
1、迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象;
2、迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
缺点:
1、迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。
使用场景:
1、系统需要访问一个聚合对象的内容而无需暴露它的内部表示;
2、系统需要支持对聚合对象的多种遍历;
3、系统需要为不同的聚合结构提供一个统一的接口。
C#设计模式之16-迭代器模式的更多相关文章
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- 《Head first设计模式》之迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了! 真是个好消息!现在我们可以在同一个地方,享用煎饼屋美味的煎饼早餐,和好吃 ...
- [设计模式] 16 迭代器模式 Iterator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...
- C#设计模式(16)——迭代器模式(Iterator Pattern)
一.引言 在上篇博文中分享了我对命令模式的理解,命令模式主要是把行为进行抽象成命令,使得请求者的行为和接受者的行为形成低耦合.在一章中,将介绍一下迭代器模式.下面废话不多说了,直接进入本博文的主题. ...
- 设计模式のIteratorPattern(迭代器模式)----行为模式
一.产生背景 迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式.这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示. 二.实现方式 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- 大话设计模式Python实现-迭代器模式
迭代器模式(Iterator Pattern):提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示. 下面是一个迭代器模式的demo: #!/usr/bin/env python # - ...
- 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素
模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...
- 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相信相信的力量! 从懵懂的少年,到拿起键盘,可以写一个Hell ...
- C#设计模式系列:迭代器模式(Iterator)
迭代器模式把对象的职责分离,职责分离可以最大限度减少彼此之间的耦合程度,从而建立一个松耦合的对象.职责分离的要点是对被分离的职责进行封装,并以抽象的方式建立彼此之间的关系. 1.迭代器模式简介 1.1 ...
随机推荐
- navcat 增删改查
navcat // sql 语句结尾的地方需要 设置为空 SELECT * FROM users ; UPDATE users SET uname = 'hezhi' WHERE uid = 3 // ...
- HTTP的实体数据
数据类型表示实体数据的内容是什么,使用的是MIME type,相关的头字段是Accept和Content-Type: text:即文本格式的可读数据,我们最熟悉的应该就是text/html ...
- android 文件读写权限的设定
读取本地文件的权限问题 2016年08月15日 21:41:30 阅读数:2520 在一个音乐app过程中需要读取手机本地内存卡中的音乐文件并可以播放,具体遇到的问题如下:工程没有错误,运行出现以下信 ...
- heredoc
Heredoc在正规的PHP文档中和技术书籍中一般没有详细讲述.他是一种Perl风格的字符串输出技术.使用heredoc技术可以实现界面与代码的准分离,比如phpwind模板.规则如下:1.”< ...
- 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化
<数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...
- 中缀转逆波兰表达式 c++ 队列,栈
记得早在几十天以前,xty 学长曾让我学这个.一直推到了现在哈 咕咕咕(能鸽善鹉orz) 抱歉,学妹我来还愿了! 中缀表达式比较适合人类的计算,但是后缀表达式更适合机器计算(毕竟没有那么多运算符优先级 ...
- PHP timezone_name_get() 函数
------------恢复内容开始------------ 实例 返回时区的名称: <?php$tz=timezone_open("Europe/Paris");echo ...
- PHP xml_parser_get_option() 函数
定义和用法 xml_parser_get_option() 函数从 XML 解析器获取选项.高佣联盟 www.cgewang.com 如果成功,该函数则返回选项值.如果失败,则返回 FALSE 和一个 ...
- PHP strtolower() 函数
实例 把所有字符转换为小写: <?php高佣联盟 www.cgewang.comecho strtolower("Hello WORLD.");?> 定义和用法 str ...
- 下载excel模板,导入数据时需要用到
页面代码: <form id="form1" enctype="multipart/form-data"> <div style=" ...