目录
迭代器模式【Iterator Pattern】,什么是迭代器模式?作用?优缺点?应用场景?典型应用?实现案例?
什么是迭代器模式(Iterator Pattern)?
迭代器模式是一种行为型设计模式,它提供了一种方法,能够顺序访问一个聚合对象(如集合、列表等)的各个元素,而不需要暴露其内部的实现细节。迭代器模式主要用于遍历集合中的元素,屏蔽具体集合类的实现,使得集合的遍历操作独立于集合本身。
迭代器模式核心思想
迭代器模式的核心思想是将集合对象的遍历行为抽取出来,通过迭代器对象来执行遍历。迭代器封装了访问集合元素的逻辑,从而使集合对象和遍历方式解耦。
迭代器模式结构
(1)迭代器接口(Iterator)
定义了遍历集合所需的操作接口,例如 hasNext()、next() 和 remove() 方法,用于判断是否还有元素、获取下一个元素以及删除当前元素。
(2)具体迭代器(Concrete Iterator)
实现了 Iterator 接口,具体实现了遍历集合的方法,保存当前遍历的位置。
(3)聚合接口(Aggregate)
定义了创建迭代器的接口,通常是一个 createIterator() 方法。这个接口使得客户端能够获取一个迭代器对象,开始遍历集合。
(4)具体聚合(Concrete Aggregate)
实现了聚合接口,负责存储元素,并实现创建具体迭代器的方法。
迭代器模式的作用
(1)简化集合遍历
客户端可以通过迭代器顺序访问集合元素,而无需了解集合的内部结构。
(2)解耦遍历算法和集合
遍历行为被独立封装在迭代器中,不依赖于具体的集合类型,使得集合和遍历方式解耦。
(3)统一访问方式
不同类型的集合都可以通过实现相同的迭代器接口,提供统一的访问方式,增强系统的灵活性。
迭代器模式的优缺点
优点
(1)遍历过程封装:迭代器封装了遍历集合的逻辑,简化了集合的访问操作,并且提供了一个统一的访问接口。
(2)解耦遍历算法与集合对象
客户端无需知道集合的内部结构或实现细节,只需通过迭代器接口进行操作,增强了代码的可维护性和扩展性。
(3)多样化遍历方式
可以很容易地更改或扩展迭代器,实现不同的遍历算法(例如:正向遍历、逆向遍历等)。
缺点
(1)类的复杂性增加
每个集合都需要定义相应的迭代器类,增加了类的数量,导致系统复杂度提升。
(2)性能开销
在某些情况下,迭代器可能会带来一定的性能开销,尤其是在实现复杂的遍历算法时。
迭代器模式的应用场景
(1)访问集合对象的内容
当需要访问一个集合对象中的元素,而不希望暴露其内部实现时,迭代器模式非常合适。例如,在 Java 中,List、Set 等集合类都使用了迭代器模式。
(2)支持多种遍历方式
如果需要支持不同的遍历方式(例如顺序遍历、逆序遍历等),可以使用迭代器模式来封装不同的遍历算法。
(3)需要统一遍历接口
当需要对不同类型的聚合对象(如数组、链表等)进行统一处理时,迭代器模式可以为所有聚合对象提供一致的遍历方式。
(4)隐藏遍历算法的复杂性
当集合的遍历算法比较复杂时,迭代器可以隐藏其复杂性,客户端只需调用迭代器接口方法即可完成遍历。
迭代器模式的典型应用
(1)Java 集合框架
Iterator 接口是 Java 集合框架的重要组成部分,几乎所有的集合类都实现了 Iterator 接口。
(2)数据库结果集遍历
在 JDBC 中,ResultSet 也是一种迭代器,用于遍历查询结果集中的行。
(3)树结构遍历
在文件系统、UI控件树等场景中,迭代器可以用于遍历树结构的节点。
迭代器模式实现案例
1、定义一个Iterator接口;迭代器接口,聚合接口(Aggregate)
package com.uhhe.common.design.iterator;
import java.util.Iterator;
/**
* 定义一个Iterator接口
*
* @author nizhihao
* @version 1.0.0
* @date 2023/3/1 9:54
*/
@SuppressWarnings("all")
public interface IProjectIterator extends Iterator {
}
2、定义一个项目接口
package com.uhhe.common.design.iterator;
/**
* 定义一个接口,所有的项目都是一个接口
*
* @author nizhihao
* @version 1.0.0
* @date 2023/3/1 9:52
*/
public interface IProject {
/**
* 增加项目
*
* @param name 名称
* @param num 人数
* @param cost 费用
*/
void add(String name, int num, int cost);
/**
* 从老板这里看到的就是项目信息
*
* @return 项目信息
*/
String getProjectInfo();
/**
* 获得一个可以被遍历的对象
*
* @return IProjectIterator
*/
IProjectIterator iterator();
}
3、项目迭代器(Concrete Iterator)
package com.uhhe.common.design.iterator;
import java.util.ArrayList;
/**
* 项目迭代器
*
* @author nizhihao
* @version 1.0.0
* @date 2023/3/1 9:55
*/
public class ProjectIterator implements IProjectIterator {
/**
* 所有的项目都放在这里ArrayList中
*/
private final ArrayList<IProject> projectList;
/**
* 当前项目下标
*/
private int currentItem = 0;
/**
* 构造函数传入projectList
*
* @param projectList 项目列表
*/
public ProjectIterator(ArrayList<IProject> projectList) {
this.projectList = projectList;
}
/**
* 判断是否还有元素,必须实现
*
* @return true有|false无
*/
@Override
public boolean hasNext() {
//定义一个返回值
boolean b = true;
if (this.currentItem >= projectList.size() || this.projectList.get(this.currentItem) == null) {
b = false;
}
return b;
}
/**
* 取得下一个值
*
* @return 一个项目
*/
@Override
public IProject next() {
return this.projectList.get(this.currentItem++);
}
/**
* 删除一个对象
*/
@Override
public void remove() {
// 暂时没有使用到
}
}
4、具体项目;具体聚合(Concrete Aggregate)
package com.uhhe.common.design.iterator;
import java.util.ArrayList;
/**
* 具体项目
*
* @author nizhihao
* @version 1.0.0
* @date 2023/3/1 9:53
*/
public class Project implements IProject {
/**
* 定义一个项目列表,说有的项目都放在这里
*/
private final ArrayList<IProject> projectList = new ArrayList<>();
/**
* 项目名称
*/
private String name = "";
/**
* 项目成员数量
*/
private int num = 0;
/**
* 项目费用
*/
private int cost = 0;
public Project() {
}
/**
* 定义一个构造函数,把所有老板需要看到的信息存储起来
*
* @param name 名称
* @param num 人数
* @param cost 费用
*/
private Project(String name, int num, int cost) {
// 赋值到类的成员变量中
this.name = name;
this.num = num;
this.cost = cost;
}
/**
* 增加项目
*
* @param name 名称
* @param num 人数
* @param cost 费用
*/
@Override
public void add(String name, int num, int cost) {
this.projectList.add(new Project(name, num, cost));
}
/**
* 得到项目的信息
*
* @return 项目信息
*/
@Override
public String getProjectInfo() {
String info = "";
// 获得项目的名称
info = info + "项目名称:" + this.name;
// 获得项目人数
info = info + "\t项目人数: " + this.num;
// 项目费用
info = info + "\t项目费用:" + this.cost;
return info;
}
/**
* 产生一个遍历对象
*
* @return IProjectIterator
*/
@Override
public IProjectIterator iterator() {
return new ProjectIterator(this.projectList);
}
}
5、老板来看项目了
package com.uhhe.common.design.iterator;
/**
* 老板来看项目信息了
*
* @author nizhihao
* @version 1.0.0
* @date 2023/3/1 9:57
*/
public class Boss {
/**
* 迭代器模式【Iterator Pattern】
* <p>
* java.util.Iterable 接口只有一个方法:iterator(),也就说通过 iterator()这个方法去遍历聚集类中的所有方法或属性,
* 基本上现在所有的高级的语言都有 Iterator 这个接口或者实现
*/
public static void main(String[] args) {
// 定义一个List,存放所有的项目对象
IProject project = new Project();
// 增加星球大战项目
project.add("星球大战项目", 10, 100000);
// 增加扭转时空项目
project.add("扭转时空项目", 100, 10000000);
// 增加超人改造项目
project.add("超人改造项目", 10000, 1000000000);
// 这边100个项目
for (int i = 1; i < 100; i++) {
project.add("第" + i + "个项目", i * 5, i * 1000000);
}
// 遍历一下ArrayList,把所有的数据都取出
IProjectIterator projectIterator = project.iterator();
while (projectIterator.hasNext()) {
IProject p = (IProject) projectIterator.next();
System.out.println(p.getProjectInfo());
}
}
}
总结:
迭代器模式通过提供统一的接口,简化了集合对象的遍历过程,解耦了集合对象与遍历算法,增强了代码的灵活性和可扩展性。它非常适用于需要对集合对象进行顺序访问的场景,同时也广泛应用于现代编程语言的集合框架中。