登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
博客
发1篇日志+1圆
记录
发1条记录+2圆币
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
VIP申请
VIP网盘
网盘
联系我们
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
设计模式(十六)迭代器
设计模式(十六)迭代器
[ 复制链接 ]
姊囝
2025-6-9 08:27:42
一、定义
提供一种方法顺序访问一个聚合对象中的各个元素,且不用暴露该对象的内部表示。迭代器模式是一种对象行为型模式,又称为游标(Cursor)模式。
二、描述
在软件系统中,聚合对象拥有两个职责:一是存储数据,二是遍历数据。从依赖性来看,前者是聚合对象的基本职责,而后者既是可变化的,又是可分离的。因此,可以将遍历数据的行为从聚合对象中分离出来,封装在迭代器对象中,由迭代器来提供遍历聚合对象内部数据的行为,这将简化聚合对象的设计,更加符合单一职责原则的要求。包含以下四个角色:
1、Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法。
2、ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。
3、Aggregate(抽象聚合类):它用于存储和管理元素对象,声明一个CreateIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。
4、ConcreteAggregate(具体聚合类):它是抽象聚合类的子类,实现了在抽象聚合类中声明的CreateIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。
三、例子
X公司为某商场开发了一套销售管理系统,在对该系统进行分析和设计时,M公司开发人员发现经常需要对系统中的商品数据、客户数据等进行遍历,为了复用这些遍历代码,开发人员设计了一个抽象的数据聚合类AbstractObjectList,而将存储商品和客户登记的类作为其子类。
AbstractObjectList:抽象聚合类
public abstract class AbstractObjectList
{
protected IList<object> objectList = new List<object>();
public AbstractObjectList (IList<object> objectList)
{
this.objectList = objectList;
}
public void AddObject(object obj)
{
this.objectList.Add(obj);
}
public void RemoveObject(object obj)
{
this.objectList.Remove(obj);
}
public IList<Object> GetObjectList()
{
return this.objectList;
}
// 声明创建迭代器对象的抽象工厂方法
public abstract AbstractIterator CreateIterator();
}
复制代码
ProductList、ProductIterator:具体聚合类、具体迭代器,具体迭代器是具体聚合类的内部类
public class ProductList : AbstractObjectList
{
public ProductList(IList<object> objectList) : base(objectList)
{
}
public override AbstractIterator CreateIterator()
{
return new ProductIterator(this);
}
private class ProductIterator : AbstractIterator
{
private ProductList productList;
private IList<object> products;
private int cursor1; // 定义一个游标,用于记录正向遍历的位置
private int cursor2; // 定义一个游标,用于记录逆向遍历的位置
public ProductIterator(ProductList productList)
{
this.productList = productList;
this.products = productList.GetObjectList(); // 获取集合对象
this.cursor1 = 0; // 设置正向遍历游标的初始值
this.cursor2 = this.products.Count - 1; // 设置逆向遍历游标的初始值
}
public object GetNextItem()
{
return products[cursor1];
}
public object GetPreviousItem()
{
return products[cursor2];
}
public bool IsFirst()
{
return cursor2 == -1;
}
public bool IsLast()
{
return cursor1 == products.Count;
}
public void Next()
{
if (cursor1 < products.Count)
{
cursor1++;
}
}
public void Previous()
{
if (cursor2 > -1)
{
cursor2--;
}
}
}
}
复制代码
AbstractIterator:抽象迭代器
public interface AbstractIterator
{
void Next(); // 移动至下一个元素
bool IsLast(); // 判断是否为最后一个元素
void Previous(); // 移动至上一个元素
bool IsFirst(); // 判断是否为第一个元素
object GetNextItem(); // 获取下一个元素
object GetPreviousItem(); // 获取上一个元素
}
复制代码
Program:客户端测试类
IList<object> products = new List<object>();
products.Add("倚天剑");
products.Add("屠龙刀");
products.Add("断肠草");
products.Add("葵花宝典");
products.Add("四十二章经");
AbstractObjectList objectList = new ProductList(products); // 创建聚合对象
AbstractIterator iterator = objectList.CreateIterator(); // 创建迭代器对象
Console.WriteLine("正向遍历");
while (!iterator.IsLast())
{
Console.Write(iterator.GetNextItem() + ",");
iterator.Next();
}
Console.WriteLine();
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine("逆向遍历");
while (!iterator.IsFirst())
{
Console.Write(iterator.GetPreviousItem() + ",");
iterator.Previous();
}
Console.ReadLine();
复制代码
四、总结
1、优点
(1)迭代器模式支持以不同方式遍历一个聚合对象,在同一个聚合对象上可以定义多种便利方式。在迭代器模式中,只需用一个不同的迭代器来替换原有迭代器即可改变遍历算法,也可以自己定义迭代器的子类以支持新的遍历方法。
(2)迭代器模式简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。
(3)在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,符合开闭原则。
2、缺点
(1)由于迭代器模式将存储数据和遍历数据的职责分离,在增加新的聚合类需要对应增加新的迭代器类,类的个数会成对增加,这在一定程度上增加了系统的复杂性。
(2)抽象迭代器的设计难度较大,需要充分考虑系统将来的扩展。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是一件很容易的事情。
迭代器模式在.Net中,可以通过实现IEnumberable接口即可,不再需要单独实现,迭代器模式中的聚集接口和迭代器接口都已经存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口则扮演的就是抽象聚集的角色,其中定义了GetEnumerator()方法。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
设计模式
十六
迭代
相关帖子
STL:迭代器与常用算法
【设计模式】单例模式
【设计模式】外观模式
【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题
没听说过设计模式?保姆级教程来了!
二叉树的中序遍历:递归法和迭代法
Golang基础笔记十六之反射
将std容器的正向迭代器转换成反向迭代器
Js 中 迭代器 与 生成器
设计模式之单例模式
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
STL:迭代器与常用算法
0
1063
南宫玉英
2025-06-23
业界
【设计模式】单例模式
0
374
嘀荼酴
2025-06-26
业界
【设计模式】外观模式
0
160
盒礁泅
2025-06-27
业界
【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题
0
878
匣卒
2025-07-08
安全
没听说过设计模式?保姆级教程来了!
0
407
涣爹卮
2025-07-09
科技
二叉树的中序遍历:递归法和迭代法
0
563
窖咎
2025-08-05
业界
Golang基础笔记十六之反射
0
208
后彼
2025-08-05
安全
将std容器的正向迭代器转换成反向迭代器
0
241
筒濂
2025-08-18
安全
Js 中 迭代器 与 生成器
0
316
骆贵
2025-08-31
安全
设计模式之单例模式
0
70
颖顿庐
2025-09-03
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
安全
签约作者
程序园优秀签约作者
发帖
姊囝
2025-6-9 08:27:42
关注
0
粉丝关注
17
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
黎瑞芝
9990
杭环
9988
4
凶契帽
9988
5
氛疵
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多