004-行为型-04-迭代器模式(Iterator)
一、概述
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
迭代模式使用比较少,JDK集合也提供了Iterator的具体实现,可以直接拿来用,不必自己实现
1.1、适用场景
1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。
1.2、优缺点
优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
1.3、类图角色及其职责

迭代模式的角色和职责
1、Iterator(迭代器接口):
该接口必须定义实现迭代功能的最小定义方法集
比如提供hasNext()和next()方法。
2、ConcreteIterator(迭代器实现类):
迭代器接口Iterator的实现类。可以根据具体情况加以实现。
3、Aggregate(容器接口):
定义基本功能以及提供类似Iterator iterator()的方法。
4、concreteAggregate(容器实现类):
容器接口的实现类。必须实现Iterator iterator()方法。
1.4、演进过程
1.4.1、初始化
创建一个容器中要存储的内容Book
public class Book {
private String id;
private String name;
private double price;
public Book(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void display() {
System.out.println("ID=" + id + ",\tname=" + name + ",\tprice" + price);
}
}
创建一个容器BookList
public class BookList {
//容器内部还是一个List,也可以用数组
private List<Book> bookList = new ArrayList<Book>();
private int index;
//添加书籍
public void addBook(Book book){
bookList.add(book);
}
//删除书籍
public void removeBook(Book book){
int bookIndex = bookList.indexOf(book);
bookList.remove(bookIndex);
}
//判断是否有下一本书
public boolean hasNext(){
if(index >= bookList.size()){
return false;
}
return true;
}
//获得下一本书
public Book getNext(){
return bookList.get(index++);
}
//获取集合长度
public int getSize(){
return bookList.size();
}
//根据index获取Book
public Book getByIndex(int index){
return bookList.get(index);
}
}
接下来,就是迭代容器了
方式一、(由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法)
@Test
public void test1() {
BookList bookList = new BookList(); Book book1 = new Book("001","设计模式",200);
Book book2 = new Book("002","Java核心编程",200);
Book book3 = new Book("003","计算机组成原理",200); bookList.addBook(book1);
bookList.addBook(book2);
bookList.addBook(book3); while(bookList.hasNext()){
Book book = bookList.getNext();
book.display();
}
}
输出
ID=001, name=设计模式, price200.0
ID=002, name=Java核心编程, price200.0
ID=003, name=计算机组成原理, price200.0
方式二、让调用者自己实现遍历。直接暴露数据细节给外部)
@Test
public void test2() {
BookList bookList = new BookList(); Book book1 = new Book("001", "设计模式", 200);
Book book2 = new Book("002", "Java核心编程", 200);
Book book3 = new Book("003", "计算机组成原理", 200); bookList.addBook(book1);
bookList.addBook(book2);
bookList.addBook(book3); for (int i = 0; i < bookList.getSize(); i++) {
Book book = bookList.getByIndex(i);
book.display();
}
}
结果同上
不使用迭代模式的缺点
以上方法1与方法2都可以实现对遍历,但有这些问题
1,容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。
2,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
应用迭代模式的条件
Iterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。
所以,Iterator模式的应用场景可以归纳为满足以下几个条件:
1、访问容器中包含的内部对象
2、按顺序访问
1.4.2、进化
用代码实现一下迭代模式,只需修改BookList即可,BookListIterator
public class BookListIterator {
//容器内部还是一个List,也可以用数组
private List<Book> bookList = new ArrayList<Book>();
private int index;
//添加书籍
public void addBook(Book book){
bookList.add(book);
}
//删除书籍
public void removeBook(Book book){
int bookIndex = bookList.indexOf(book);
bookList.remove(bookIndex);
}
//获取集合长度
public int getSize(){
return bookList.size();
}
//根据index获取Book
public Book getByIndex(int index){
return bookList.get(index);
}
//得到Iterator实例
public Iterator Iterator() {
return new Itr();
}
//内部类,Iterator实例(因为要使用容器的内部信息,所以要写成内部类)
private class Itr implements Iterator{
//判断是否有下一本书,将刚才hasNext()中内容复制过来即可
public boolean hasNext() {
if(index >= bookList.size()){
return false;
}
return true;
}
//获得下一本书,将刚才getNext()中内容复制过来即可
public Object next() {
return bookList.get(index++);
}
public void remove() {
}
}
}
测试
@Test
public void test3() {
BookListIterator bookList = new BookListIterator(); Book book1 = new Book("001","设计模式",200);
Book book2 = new Book("002","Java核心编程",200);
Book book3 = new Book("003","计算机组成原理",200); bookList.addBook(book1);
bookList.addBook(book2);
bookList.addBook(book3); Iterator iterator = bookList.Iterator();
while(iterator.hasNext()){
Book book = (Book) iterator.next();
book.display();
}
}
输出同上
可以看到,这和使用JDK提供集合的Iterator方法就一模一样了。
二、扩展
2.1 JDK
java.util.Iterator
java.util.ArrayList中的Itr
2.2 Mybatis
org.apache.ibatis.cursor.defaults.DefaultCursor的cursorIterator
c
004-行为型-04-迭代器模式(Iterator)的更多相关文章
- 【设计模式】行为型04迭代器模式(Iterator Pattern)
学习地址:http://www.runoob.com/design-pattern/iterator-pattern.html 迭代器模式,简单来说就是通过迭代的方式对集合进行遍历,在集合的学习中也一 ...
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- 迭代器模式 Iterator 行为型 设计模式(二十)
迭代器模式(Iterator) 走遍天下,世界那么大,我想去看看 在计算机中,Iterator意为迭代器,迭代有重复的含义,在程序中,更有“遍历”的含义 如果给定一个数组,我们可以通过for循 ...
- 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素
模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...
- 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)
上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...
- 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...
- 迭代器模式-Iterator(Java实现)
迭代器模式-Iterator 用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节. 本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫. 本文章的例子的继承关系图如下: 其中: Cat ...
- Java 设计模式系列(十五)迭代器模式(Iterator)
Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...
- 二十四种设计模式:迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...
随机推荐
- Spring -12 -声明式事务及完整的XML配置文件信息 -声明式事务中的相关属性(tx:advice的标签)
1.编程式事务: 1.1由程序员编程事务控制代码. 1.2OpenSessionInView 就属于编程式事务: session.commit()和rollback() 2.声明式事务: 2.1事务控 ...
- P1341 无序字母对[欧拉路]
题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 解析 毒瘤字符串读入 我就是不喜欢邻接 ...
- asp、aspx、php、jsp万能密码大全【笔记】
asp aspx万能密码 1:"or "a"="a 2: ')or('a'='a 3:or 1=1-- 4:'or 1=1-- 5:a'or' 1=1-- 6: ...
- vue input只允许输入数字
template: <input type="text" v-model="pageIndex" @keyup="inputChange&quo ...
- vue slot 插槽详解
插槽含义:就是引入子组件后,在插入子组件元素中添加信息或者标签,使得子组件的指定位置插入信息或者标签 插槽有三种:默认插槽.具名插槽.作用域插槽,由于vue2.6.0后对插槽进行修改,但是兼容2.6. ...
- MenuOS扩展(课堂时间作业)
MenuOS扩展实验 1.编译内核 2.制作根文件系统 rm menu -rf 强制删除原menu文件 git clone https://github.com/mengning/menu.git 从 ...
- Chocolatey——windows下的包管理器
前言 windows 包管理器 | https://chocolatey.org/ 命令 文档 | https://chocolatey.org/docs 根据使用会补充命令
- Linux 服务器用户间ssh免密码登录
1.本脚本为服务器用户间密码互信登录脚本 2.依赖 需要安装expect工具 3.使用 sh CreateUserssh.sh hadoop hadoop /home/hadoop/.ssh 三个带入 ...
- Jmeter批量调用web service,发送message到tibco JMS queue
[转载]Jmeter使用CSV Data Set Config参数化数据不重复的多次循环执行https://blog.csdn.net/qq_35123018/article/details/7877 ...
- 结构化异常SEH处理机制详细介绍(一)
结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能.而Visual C++中的__try{}/__finally{}和__try{}/__except{}结构本质上是对Window ...