✨这里是第七人格的博客✨小七,欢迎您的到来~✨
🍅系列专栏:设计模式🍅
✈️本篇内容: 迭代器模式✈️
🍱 本篇收录完整代码地址:https://gitee.com/diqirenge/design-pattern 🍱
楔子
很久没有更新文章了,一方面是工作比较忙,另一方面家里又迎来了新的小生命,短暂休整一下后,小七又决定出来卖艺了。今天我们聊一下迭代器模式。
需求背景
很多公司的组织架构都是树形结构,每一个节点都是一个部门,每一个部门包含很多员工,现在需要遍历这些员工,考虑使用树的深度遍历。
分析设计
在实现迭代器模式之前,我们可以先参考下 Java 中 List 类是如何实现迭代器的,类图如下
开发会按照这个模式来实现,这个模式主要分为以下⼏块;
- Collection,集合⽅法部分⽤于对⾃定义的数据结构添加通⽤⽅法; add 、 remove 、 iterator
等核⼼⽅法。
Iterable,提供获取迭代器,这个接⼝类会被 Collection 继承。
Iterator,提供了两个⽅法的定义; hasNext 、 next ,会在具体的数据结构中写实现⽅式。
UML图
根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码
模块名称
iterator
模块地址
https://gitee.com/diqirenge/design-pattern/tree/master/src/main/java/com/run2code/design/behavioral/iterator
模块描述
迭代器模式代码示例
代码实现
1、参考jdk的Iterator,编写迭代器接口
①、是否有下一个节点
②、获取下一个节点
/**
* 迭代器接口,主要提供hasNext、next两个方法,参考jdk的Iterator设计
* @see java.util.Iterator 接口
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public interface Iterator<E> {
boolean hasNext();
E next();
}
2、参考jdk的Iterable,编写Iterable,提供一个获取迭代器的方法
/**
* 提供获取迭代器的方法,参考jdk的Iterable设计
* @see java.lang.Iterable 接口
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public interface Iterable<T> {
Iterator<T> iterator();
}
3、参考jdk的Collection,编写集合接口
该接口继承Iterable,拓展了基础的添加和删除方法
/**
* 集合接口,参考jdk的Collection设计
* @see java.util.Collection 接口
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public interface Collection<E> extends Iterable<E> {
boolean add(E e);
boolean remove(E e);
Iterator<E> iterator();
}
4、编写员工类
/**
* 员工类
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public class Employee {
private String name;
private String position;
public Employee(String name, String position) {
this.name = name;
this.position = position;
}
public String getName() {
return name;
}
public String getPosition() {
return position;
}
}
5、编写组织类
实现Iterable接口,编写iterator()方法
/**
* 组织类
* 实现Iterable接口的iterator()方法,返回一个Iterator实例
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public class Organization implements Iterable<Employee> {
private List<Employee> employees;
public Organization() {
employees = new ArrayList<>();
}
public void addEmployee(Employee employee) {
employees.add(employee);
}
@Override
public Iterator<Employee> iterator() {
return new OrganizationIterator(employees);
}
}
6、编写组织器迭代类
主要完成hasNext和next两个方法的逻辑编写
/**
* 组织迭代器类
* 实现Iterator类,用于遍历组织结构中的员工。
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public class OrganizationIterator implements Iterator<Employee> {
private List<Employee> employees;
private int currentIndex;
public OrganizationIterator(List<Employee> employees) {
this.employees = employees;
currentIndex = 0;
}
@Override
public boolean hasNext() {
return currentIndex < employees.size();
}
@Override
public Employee next() {
return employees.get(currentIndex++);
}
}
7、编写测试类
/**
* 测试迭代器模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/30
*/
public class IteratorTest {
@Test
public void testIterator() {
Organization organization = new Organization();
organization.addEmployee(new Employee("张三", "经理"));
organization.addEmployee(new Employee("李四", "工程师"));
organization.addEmployee(new Employee("王五", "设计师"));
Iterator<Employee> iterator = organization.iterator();
while (iterator.hasNext()) {
Employee employee = iterator.next();
System.out.println("姓名:" + employee.getName() + ",职位:" + employee.getPosition());
}
}
}
8、测试结果
姓名:张三,职位:经理
姓名:李四,职位:工程师
姓名:王五,职位:设计师
实现要点
迭代器模式实现要点如下:
- 抽象迭代器(Iterator):定义了遍历集合对象所需的接口,通常包括
hasNext()
和next()
方法,用于判断是否还有下一个元素以及获取下一个元素。 - 具体迭代器(Iterator):实现抽象迭代器接口的具体类,负责具体的遍历逻辑。它保存了当前遍历的位置信息,并可以根据需要向前或向后遍历集合元素。
- 聚合对象(Iterable):是迭代器模式的目标对象,通常是一个集合或容器,包含了多个元素。聚合对象提供创建具体迭代器的方法,以便外部可以通过迭代器访问其内部的元素。
- 隔离集合的遍历和实现:迭代器模式将集合的遍历方式与集合的内部表示分离,使得可以在不暴露集合内部结构的情况下访问集合中的元素。
- 增加遍历的灵活性:通过迭代器模式,可以灵活地为集合对象增加不同的遍历方法,而不需要修改集合对象的代码。
- 支持多种遍历方式:迭代器模式允许定义多种遍历方式,例如顺序遍历、逆序遍历等,只需要提供相应的具体迭代器实现即可。
- 简化外部操作:外部代码只需通过迭代器的接口与集合交互,无需关心集合的内部结构和遍历细节,简化了外部代码的复杂性。
总结
迭代器模式遵循开闭原则,对扩展开放,对修改封闭。当需要增加新的遍历方式时,只需添加新的具体迭代器类,无需修改现有代码。每个类只关注一项任务,也符合单一职责原则。
面对对象面对君,不负代码不负卿