模式简介


提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

一个聚合对象,应该提供一个方法让用户访问它的元素,并且不暴露其内部结构。遍历的方式可能多种多样,我们不希望在这个聚合类中定义各种遍历的方法。这种情况下,就可以使用迭代器模式将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器对象中

结构分析


UML类图

角色说明

  • Aggregate

抽象聚合类,定义一个创建相应迭代器对象的接口。

  • ConcreteAggregate

实际聚合类,实现创建相应迭代器对象的接口,返回一个ConcreteIterator实例。

  • Iterator

抽象迭代器,定义访问和遍历元素的接口。

  • ConcreteIterator

实际迭代器,实现抽象迭代器定义的接口。

工作原理

ConcreteIterator跟踪聚合中的当前对象,通过Next方法计算出待遍历的下一个对象。

结构代码

//抽象迭代器
abstract class Iterator
{public abstract object First();public abstract object Next();public abstract bool IsDone();public abstract object CurrentItem();
}//抽象聚合类
abstract class Aggregate
{public abstract Iterator CreateIterator();
}//实际聚合类,实现Aggregate中的抽象方法CreateIterator,返回相应的迭代器
class ConcreteAggregate : Aggregate
{private ArrayList _items = new ArrayList();public override Iterator CreateIterator(){return new ConcreteIterator(this);}public object this[int index]{get { return _items[index]; }set { _items.Insert(index, value); }}public int Count{get { return _items.Count; }}
}//实际迭代器
class ConcreteIterator : Iterator
{private ConcreteAggregate _aggregate;private int _current;public ConcreteIterator(ConcreteAggregate aggregate){_aggregate = aggregate;}public override object CurrentItem(){return _aggregate[_current];}public override object First(){return _aggregate[0];}public override bool IsDone(){return _current >= _aggregate.Count - 1;}public override object Next(){object next = null;if (_current < _aggregate.Count - 1){next = _aggregate[++_current];}return next;}
}//客户端调用
static void Main(string[] args)
{ConcreteAggregate aggregate = new ConcreteAggregate();aggregate[0] = "A";aggregate[1] = "B";aggregate[2] = "C";aggregate[3] = "D";var iterator = aggregate.CreateIterator();Console.WriteLine(iterator.First());while (!iterator.IsDone()){Console.WriteLine(iterator.Next());}Console.ReadLine();
}

示例分析


本节我们通过一个遍历音乐播放列表的示例来讲述迭代器模式。首先创建一个歌曲类,包含两个属性:歌曲名称和演唱者。

class Song
{public string Name { get; set; }public string Singer { get; set; }
}

定义迭代器接口以及聚合接口。

interface Iterator
{object First();object Next();bool IsDone();object CurrentItem();
}interface IAggregate
{Iterator CreateIterator();
}

创建歌曲迭代器,包含一个歌曲列表对象,并提供对这个列表中元素访问的相关方法。

class SongIterator : Iterator
{private SongCollection _songCollection;private int _current;public SongIterator(SongCollection songCollection){this._songCollection = songCollection;}public object First(){return _songCollection[0];}public object Next(){object song = null;if (_current < _songCollection.Count - 1){song = _songCollection[++_current];}return song;}public bool IsDone(){return _current >= _songCollection.Count - 1;}public object CurrentItem(){return _songCollection[_current];}
}

歌曲聚合类,提供一个创建针对该聚合的迭代器的方法。

class SongCollection : IAggregate
{private ArrayList _songs = new ArrayList();public Iterator CreateIterator(){return new SongIterator(this);}public object this[int index]{get { return _songs[index]; }set { _songs.Insert(index, value); }}public int Count{get { return _songs.Count; }}
}

客户端调用:

class Program
{static void Main(string[] args){SongCollection songs = new SongCollection();songs[0] = new Song { Name = "Dance To This", Singer = "Troye Sivan" };songs[1] = new Song { Name = "Ferrari", Singer = "Bebe Rexha" };songs[2] = new Song { Name = "Ocean", Singer = "Martin Garrix" };songs[3] = new Song { Name = "Sober", Singer = "Demi Lovato" };songs[4] = new Song { Name = "Only You", Singer = "Cheat Codes" };Iterator iterator = songs.CreateIterator();var firstSong = iterator.First() as Song;Console.WriteLine($"First Song:{firstSong.Name},Singer:{firstSong.Singer}");while (!iterator.IsDone()){var currentSong = iterator.Next() as Song;Console.WriteLine($"Now Playing:{ currentSong.Name},Singer:{currentSong.Singer}");}Console.ReadLine();}
}

运行结果:

在C#中,我们可以使用foreach语句轻松遍历实现IEnumerable和IEnumerator接口的集合。

List<Song> songs = new List<Song>();
songs.Add(new Song { Name = "Dance To This", Singer = "Troye Sivan" });
songs.Add(new Song { Name = "Ferrari", Singer = "Bebe Rexha" });
songs.Add(new Song { Name = "Ocean", Singer = "Martin Garrix" });
songs.Add(new Song { Name = "Sober", Singer = "Demi Lovato" });
songs.Add(new Song { Name = "Only You", Singer = "Cheat Codes" });foreach (var song in songs)
{Console.WriteLine($"Now Playing:{ song.Name},Singer:{song.Singer}");
}

使用场景


  • 访问一个聚合对象的内容而无需暴露它的内部表示。

  • 支持对聚合对象的多种遍历。
  • 为遍历不同的聚合结构提供一个统一的接口。

转载于:https://www.cnblogs.com/Answer-Geng/p/9240419.html

设计模式(十七)—— 迭代器模式相关推荐

  1. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  2. 【GOF23设计模式】迭代器模式

    [GOF23设计模式]迭代器模式 来源:http://www.bjsxt.com/  一.[GOF23设计模式]_迭代器模式.JDK内置迭代器.内部类迭代器 1 package com.test.it ...

  3. [转载] Python进阶:设计模式之迭代器模式

    参考链接: Python中的迭代器 在软件开发领域中,人们经常会用到这一个概念--"设计模式"(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一 ...

  4. 每日学一个设计模式1——迭代器模式

    引言 精通设计模式是从码农脱颖而出的条件之一.跟着<图解设计模式>这本书学习设计模式,从今天开始,一天总结一个设计模式. 迭代器模式(一个一个遍历) 用处 隐藏遍历集合的内部结构,遍历不同 ...

  5. php迭代器实例,php设计模式之迭代器模式实例分析【星际争霸游戏案例】

    本文实例讲述了php设计模式之迭代器模式.分享给大家供大家参考,具体如下: 星际的任务关一般会有这样的设定:一开始电脑的农民不采矿,如果战斗打响,或者玩家造出第一个兵,电脑的农民开始采矿. 我们自然会 ...

  6. 设计模式之迭代器模式(Iterator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  7. 设计模式复习-迭代器模式

    Iterator.H #pragma once #include <list> #include <windows.h> using namespace std;/* 设计模式 ...

  8. php foreach 循环 判断index 小于多少_PHP设计模式之迭代器模式 - 硬核项目经理

    一说到这个模式,就不得不提循环语句.在<大话设计模式>中,作者说道这个模式现在的学习意义更大于实际意义,这是为什么呢?当然就是被foreach这货给整得.任何语言都有这种类似的语法可以方便 ...

  9. Java 设计模式之迭代器模式

    一.了解迭代器模式 1.1 什么是迭代器模式 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式把游走的任务放在迭代器上,而不是聚合上.这样简化了聚合的接口和 ...

  10. 设计模式:迭代器模式(Iterator)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

最新文章

  1. 温网停赛,AI不停赛:斯坦福新研究模拟网球名将打比赛
  2. 连接远程ms sql server 2000企业版时出现错误:10061的解决方法
  3. P2486 [SDOI2011]染色
  4. oauth2.0 学习案例demo_Vue3教程:用 Vue3 开发小程序,这里有一份实际的代码案例!...
  5. 黄聪:移动应用抓包调试利器Charles
  6. Android 加载网页进度条
  7. [hadoop源码阅读][0]-初衷和各种资源
  8. IPTV电视直播系统apk运营—怎么让视频更流畅
  9. 使用pbrt遇到的问题及解决方法
  10. c语言源程序的单位,C语言源程序的基本单位是什么
  11. spark scala求PV,UV,topN
  12. 关于把Excel转换成word的经验
  13. Spyder学习笔记1-Jack Xu
  14. 怎么用显卡计算_会议租车价格多少钱,上海会议租车费用怎么计算?
  15. 使用计算机时应先按,计算机应用基础试卷及答案
  16. 基于滴滴云服务器搭建 Consul 集群
  17. 逆讯图驴企业版,这一次颜值更高
  18. 【30分钟学完】canvas动画|游戏基础(7):动量守恒与多物体碰撞
  19. 忆鲁迅《故乡》中的一句话
  20. 异常:Handling ClientRegistrationException error: No client with requested id: null

热门文章

  1. 那个清华哈佛双料女学霸, 辞职了
  2. 【译】R包介绍:Online Random Forest
  3. pku 1459 最大流 SAP
  4. 关于暂停或终止更新的相关读书笔记
  5. GitHub 给已存在的仓库增加开原协议LICENSE
  6. 在ubuntu上搭建开发环境1---在windows7的基础上在安装ubuntu(双系统)
  7. 课程 3: Content Providers 简介
  8. python中判断文本的编码格式
  9. Docker之数据卷和数据卷容器
  10. Web服务及http协议_学习笔记