初涉c#设计模式-Iterator Pattern

一、迭代器模式简介(Brief Introduction)

  迭代器模式(Iterator Pattern),提供一种方法顺序访问一个聚合对象中元素,而不暴露改集合对象的内部表示。

  Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

二、解决的问题(What To Solve)

      在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。

  当需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,应该考虑用迭代器模式;当需要对聚集有多种方式遍历时,可以考虑使用迭代器模式。其中,你不用关心到底是什么样子的数组作为对象集合,是Array,是List还是简单的数组,迭代器模式会提供给你一个聚合对象的遍历方式,而不用去了解具体是在遍历什么类型的聚合对象。

三、代码:

View Code
using System;
using System.Collections.Generic;
using System.Text;namespace IteratePattern
{public class Guest{public string id{get;set;}public string name{get;set;}public Guest(string aId, string aName){id = aId;name = aName;}}public interface IAggrate{IIterator GetIterator();}public class ConcreateAggrate:IAggrate{List<object> _guest = new List<object>();public IIterator GetIterator(){return new ConcreateIterator(this);}public object this[int index]{get{return _guest[index];}set{_guest.Add(value);}}public int count(){return _guest.Count;}}public interface IIterator{bool Next();}class ConcreateIterator : IIterator{ConcreateAggrate _aggrate;int currentindex;public ConcreateIterator(ConcreateAggrate aAggrate){_aggrate = aAggrate;currentindex = -1;}public object Current{get { return _aggrate[currentindex]; }}public bool Next(){currentindex++;return _aggrate.count() > currentindex;}}class Program{static void Main(string[] args){ConcreateAggrate aAggrate = new ConcreateAggrate();aAggrate[0] = new Guest("1", "hi");aAggrate[1] = new Guest("2", "my");aAggrate[2] = new Guest("3", "dear");aAggrate[3] = new Guest("4", "iterator");aAggrate[4] = new Guest("5", "pattern");//ConcreateIterator aIterator = new ConcreateIterator(aAggrate);ConcreateIterator aIterator = (ConcreateIterator)aAggrate.GetIterator();while (aIterator.Next())Console.WriteLine(((Guest)aIterator.Current).name);}}
}

 

举例Iterator应用

image

  下面是迭代器所拥有的最小集合,Current是属性,只能Get不能Set。还有两个方法:MoveNext是往下一个元素走,如果访问到最后一个元素之后没有元素了,就返回False;Reset是复位,回到初始位置。

image

  如果有一个容器实现了IEnumerable接口,它就可以支持我们的迭代操作了。这种设计模式已经内化为C#语言的一种元素了,就是Foreach关键字。我们定义的容器首先要实现IEnumerable接口,实现的GetEnumerator方法要返回一个IEnumerator的类型的集合。

View Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;namespace IteratePattern
{public class Guest{public string id{get;set;}public string name{get;set;}public Guest(string aId, string aName){id = aId;name = aName;}}public class ConcreateAggrate:IEnumerable{List<object> _guest = new List<object>();public object this[int index]{get{return _guest[index];}set{_guest.Add(value);}}public int count(){return _guest.Count;}#region IEnumerable 成员IEnumerator IEnumerable.GetEnumerator(){return new ConcreateIterator(this);}#endregion}class ConcreateIterator : IEnumerator{ConcreateAggrate _aggrate;int currentindex;public ConcreateIterator(ConcreateAggrate aAggrate){_aggrate = aAggrate;currentindex = -1;}#region IEnumerator 成员object IEnumerator.Current{get { return _aggrate[currentindex]; }}bool IEnumerator.MoveNext(){currentindex++;return _aggrate.count() > currentindex;}void IEnumerator.Reset(){currentindex = -1;}#endregion}class Program{static void Main(string[] args){ConcreateAggrate aAggrate = new ConcreateAggrate();aAggrate[0] = new Guest("1", "hi");aAggrate[1] = new Guest("2", "my");aAggrate[2] = new Guest("3", "dear");aAggrate[3] = new Guest("4", "iterator");aAggrate[4] = new Guest("5", "pattern");foreach (Guest aGuest in aAggrate)Console.WriteLine(aGuest.name);}}
}

 

  Foreach的工作机制

IEnumerator ietor = aAggrate.GetEnumerator();while(ietor.MoveNext()){Guest aGuest = (Guest)ietor.Current;Console.WriteLine(aGuest);}

 

 

遍历代码中访问的全部是接口,而不用关心集合的内部结构。上面的代码等同于下面的Foreach。

image

结构(Structure)

 

Iterator模式的几个要点

  迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。例如假设我们有一个求和算法

image

  它可以操作在多个支持迭代器的集合上,如果把这个算法写成ArrayList的话,就会非常受限制。同时我们更可以用C#的Foreach语句来写。

image

  我们的算法应该是独立的,写的时候应该尽量操作接口,这样我们写好一个算法,就能应对N种集合的变化,使得同样的算法能在不同的集合上操作。迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。也就是说,我们在迭代的时候,应该只是读取操作,不能更改容器的接口,例如遍历的时候删除一个元素,这样是不可以的。容器的结构师绝对不能碰的,一旦结构更改,遍历就会出问题。

image

  下面这种情况对i进行更改,是不会影响原来的数组内容的,因为i是int类型,它只是一份拷贝。

image

image

  我们一定要给用户提供尽量纯只读的迭代。保证每个元素被且只被遍历一次。

(引自:山天大畜博客园,http://www.cnblogs.com/cdts_change/archive/2010/10/17/1853689.html)

总结(Conclusion)

从上面的几个示例中就可以看出,尽管我们没有显示的引用迭代器,但实质还是通过迭代器来遍历的。总地来说,迭代器模式就是分离了集合对象的迭代行为,抽象出一个迭代器类来负责,这样既可做到不暴露集合的内部结构,又可以让外部代码可以透明的访问集合内部的元素。

  迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,是非常普遍的应用,但由于它太普遍了,所以各种高级语言都对他进行了封装,所以反而给人感觉此模式本身不太常用了。

 

转载请注明出处:Edward_jie,http://www.cnblogs.com/promise-7/archive/2012/05/28/2521918.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Buttons——CSS按钮样式库

点击进入查看官网说明 不同颜色按钮&#xff1a; <button class"button button-3d button-primary">button1</button><button class"button button-3d button-action">button2</button><button class"button button-3d b…

Win10中如何找到并打开SqlServer2008 R2配置管理器

首先Win R &#xff0c;打开运行窗口&#xff0c;然后输入&#xff1a; SQLServerManager10.msc

机器学习中的相似性度量

在做分类时常常需要估算不同样本之间的相似性度量(Similarity Measurement)&#xff0c;这时通常采用的方法就是计算样本间的“距离”(Distance)。采用什么样的方法计算距离是很讲究&#xff0c;甚至关系到分类的正确与否。 本文的目的就是对常用的相似性度量作一个总结。 本文…

EF中DB First模式下数据库中表结构变化时如何快速同步到EF模型中

没想到什么好的精准的办法&#xff0c;持续的报错&#xff0c;然后定位报错很是头疼。我目前感觉较快方式有两种&#xff0c;如果有更好的方式&#xff0c;请大家指教。 一、先在数据库中修改表的结构属性&#xff0c;再删除edmx文件中对应的实体类模型&#xff0c;然后再是“从…

Oracle 游标范例

create or replace procedure sp_CurTestiscursor cur is select * from tUserinfo ;beginfor user in curloopinsert into job_test(id,jobcontent,jobtime) values(user.Dept_ID,user.Username,sysdate); end loop;end;

浅析CSS选择器

假设存在如下元素&#xff1a; <p>who am i</p> 元素选择器&#xff1a; 一个元素用同一种样式&#xff1a; p {color:green; } 多个元素用同一种样式&#xff1a; p,h1,h2{color:green; } 所有元素的背景色为黑色&#xff1a; * {background:black; } <…

HTML5 FileReader API 测试(一)

2019独角兽企业重金招聘Python工程师标准>>> 参考文章 html5之FileReader接口 http://zhangyaochun.iteye.com/blog/1487900 1、FileReader接口的作用&#xff1a; 用来把文件读入内存&#xff0c;并且读取文件中的数据。 2、支持情况 FF3.6| Chrome6 Js代码 /*…

Bootstrap模态框居中显示

Bootstrap默认的模态框不是居中显示的&#xff0c;需要稍微修改下源代码&#xff1a; 1、打开源码bootstrap.js&#xff0c;在里面找到如下代码&#xff1a; 2、在上述代码段落下面增加居中的代码即可&#xff1a; //使弹出框居中。。。var $modal_dialog $(this.$element[0]…

Java_BigInteger

字段摘要 static BigInteger ONE BigInteger 的常量 1。 static BigInteger TEN BigInteger 的常量 10。 static BigInteger ZERO BigInteger 的常量 0。 构造方法摘要 BigInteger(byte[] val) 将包含 BigInteger 的二进制补码表示形式的 byte 数组转换为 BigIntege…

Bootstrap模态框显示时有阴影遮罩层

如下图所示&#xff1a; 有遮罩层在&#xff0c;无法进行任何操作&#xff0c;只需修改默认 z-index 属性即可&#xff1a; .modal-backdrop{z-index:0;}

windows 如何在Windows命令行下配置IP地址

有时候系统发生问题&#xff0c;网络连接中看不到本地连接&#xff0c;网卡工作还是正常的。这样一来却没有办法修改本地的IP地址了。因为通常都是在本地连接属性中修改IP的&#xff0c;但现在本地连接已经看不到了&#xff0c;在命令行下用IPconfig可以查看IP地址&#xff0c;…

JQuery Datatables 在Bootstrap tab中列名无法对齐的问题

如下图所示&#xff1a; 增加一句代码即可&#xff1a; $(a[data-toggle"tab"]).on(shown.bs.tab, function (e) {//当切换tab时&#xff0c;强制重新计算列宽$.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();});

C# 值类型与引用类型(1)

1. 主要内容 类型的基本概念 值类型深入 引用类型深入 值类型与引用类型的比较及应用 2. 基本概念 C#中&#xff0c;变量是值还是引用仅取决于其数据类型。 C#的基本数据类型都以平台无关的方式来定义&#xff0c;C#的预定义类型并没有内置于语言中&#xff0c;而是内置于.NET …

Bootstrap-select使用说明

背景 Bootstrap-select 是一款基于JQuery的 下拉菜单 插件&#xff0c;支持搜索和多项选择功能&#xff0c;支持Booststrap。 点击这里进入Bootstrap-select中文官方网站 使用效果如下图所示&#xff1a; 常用属性 初始化&#xff1a; <select class"selectpicker…

前端插件——Bootstrap Dual Listbox 简介

背景 Bootstrap Dual Listbox是一款基于Bootstrap的双向select选择框控件&#xff0c;作为对multiple select的扩展&#xff0c;使用起来非常简单&#xff0c;功能也更强大。 参考文章一 参考文章二 使用效果如下图所示&#xff1a; 初始化HTML代码&#xff1a; <div cla…

Fork()概念

对于刚刚接触Unix/Linux操作系统&#xff0c;在Linux下编写多进程的人来说&#xff0c;fork是最难理解的概念之一&#xff1a;它执行一次却返回两个值。 首先我们来看下fork函数的原型&#xff1a; &#xff03;i nclude <sys/types.h> &#xff03;i nclude <unistd.…

EF中报错:附加类型“xxxx”的实体失败,因为相同类型的其他实体已具有相同的主键值。

报错全文&#xff1a; 附加类型“Model.DepartProduct”的实体失败&#xff0c;因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值&#…

Nsis打包exe

2019独角兽企业重金招聘Python工程师标准>>> 这里用nsis的eclipse插件来打包exe。插件地址&#xff1a;http://eclipsensis.sf.net/update 安装完毕之后创建一个java程序&#xff0c;导出一个可执行的jar文件&#xff0c;名字JavaApp.jar。现在开始准备打包制作安装…

Bootstrap 幻灯片效果

<!--轮播图--><div class"container"><div class"carousel slide" id"slidershow" data-ride"carousel" data-interval"2000" style"margin-top:70px"><!--计数器--><ol class"c…

lightbox自定义图片大小的实现

lightbox的功能非常强大&#xff0c;但是lightbox有个很不人性话的地方就是不能自定义弹出层图片的大小&#xff08;也许是我自己不会用吧&#xff09; 切入正题 打开lightbox.js 设定两个变量 var lbxMaxWidth 600;//弹出层最大宽度&#xff0c;var lbxMaxHeight 500;//弹出…