当前位置: 首页 > ds >正文

设计模式-迭代器模式

写在前面

Hello,我是易元,这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误,欢迎大家留言指正!

案例

假设有一个Book类和一个管理书籍的BookCollection类,我们需要遍历BookCollection类中所有书籍信息。

一、传统实现:直接硬编码遍历逻辑

1. 基础代码

直接在集合类中添加遍历方法

图书类
public class Book {  private String title;  private String author;  private int publishYear;  public Book() {}  public Book(String title, String author, int publishYear) {  this.title = title;  this.author = author;  this.publishYear = publishYear;  }  // Getter 和 Setter 方法  public String getTitle() { return title; }  public void setTitle(String title) { this.title = title; }  public String getAuthor() { return author; }  public void setAuthor(String author) { this.author = author; }  public int getPublishYear() { return publishYear; }  public void setPublishYear(int publishYear) { this.publishYear = publishYear; }  @Override  public String toString() {  return "Book{" +  "title='" + title + '\'' +  ", author='" + author + '\'' +  ", publishYear=" + publishYear +  '}';  }  
}  
图书集合类
public class BookCollection {  private List<Book> books;  public BookCollection() {}  public BookCollection(List<Book> books) {  this.books = books;  }  public void printBooks() {  for (Book book : books) {  System.out.println(book.toString());  }  }  
}  
测试代码
@Test  
public void printBookTest() {  List<Book> books = new ArrayList<>();  books.add(new Book("Java编程思想", "Bruce Eckel", 2018));  books.add(new Book("设计模式", "Erich Gamma", 1994));  books.add(new Book("鸟哥的Linux私房菜", "鸟哥", 2010));  BookCollection bookCollection = new BookCollection(books);  bookCollection.printBooks();  
}  

3. 存在的缺陷

以上述代码为例,若需要新的遍历方式(如按作者或出版年份遍历),一种方法是直接在BookCollection中添加新方法。这会破坏原有代码,每次新增遍历方式都需要修改BookCollection类。

二、设计模式实现

1. 迭代器模式

迭代器模式提供了一种遍历集合对象元素的方式,而无需暴露其内部表示。它定义了访问集合元素的接口,支持遍历不同的集合结构。
er

  • 主要角色
    • Iterator(迭代器):定义访问和遍历集合元素的接口。

    • ConcreteIterator(具体迭代器):实现迭代器接口,用于遍历集合。

    • Aggregate(集合):定义创建迭代器的接口。

    • ConcreteAggregate(具体集合):实现集合接口,返回具体迭代器实例。

2. 使用设计模式对已实现的功能进行重构

迭代器接口
public interface BookIterator {  boolean hasNext();  Book getNext();  
}  
  • 定义标准化遍历协议:
    • hasNext():检查是否存在下一个元素

    • getNext():获取当前元素并后移指针

  • 解耦集合结构与遍历逻辑的入口

具体迭代器
public class BookCollectionIterator implements BookIterator {  private List<Book> books;  private int position = 0;  public BookCollectionIterator(List<Book> books) {  this.books = books;  }  @Override  public boolean hasNext() {  return position < books.size();  }  @Override  public Book getNext() {  if (hasNext()) {  return books.get(position++);  }  return null;  }  
}  
  • 通过position索引跟踪遍历进度

  • 集合数据通过构造函数注入,保证迭代器独立性

集合接口
public interface BookAggregate {  BookIterator createIterator();  
}  
具体集合
public class BookCollection implements BookAggregate {  private List<Book> books;  public BookCollection(List<Book> books) {  this.books = books;  }  @Override  public BookIterator createIterator() {  return new BookCollectionIterator(books);  }  
}  
  • 通过createIterator()统一创建迭代器,隐藏实现细节

  • 新增迭代器无需修改集合类,只需扩展新实现

测试代码
@Test  
public void test_book_def() {  List<Book> books = new ArrayList<>();  books.add(new Book("Java编程思想", "Bruce Eckel", 2018));  books.add(new Book("Effective Java", "Joshua Bloch", 2018));  books.add(new Book("设计模式", "Erich Gamma", 1994));  books.add(new Book("鸟哥的Linux私房菜", "鸟哥", 2010));  BookAggregate bookCollection = new BookCollection(books);  BookIterator bookIterator = bookCollection.createIterator();  while (bookIterator.hasNext()) {  Book book = bookIterator.getNext();  System.out.println(book.toString());  }  
}  
输出结果
Book{title='Java编程思想', author='Bruce Eckel', publishYear=2018}  
Book{title='Effective Java', author='Joshua Bloch', publishYear=2018}  
Book{title='设计模式', author='Erich Gamma', publishYear=1994}  
Book{title='鸟哥的Linux私房菜', author='鸟哥', publishYear=2010}  

3. 增加按照出版年份进行遍历

新增具体集合类
// 按年份过滤的集合  
public class BookYearAggregate implements BookAggregate {  private List<Book> books;  private int targetYear;  public BookYearAggregate(List<Book> books, int targetYear) {  this.books = books;  this.targetYear = targetYear;  }  @Override  public BookIterator createIterator() {  return new YearBookIterator(books, targetYear);  }  
}  
新增具体迭代器
// 按出版年份过滤的迭代器  
public class YearBookIterator implements BookIterator {  private List<Book> books;  private int targetYear;  private int position = 0;  public YearBookIterator(List<Book> books, int year) {  this.books = books;  this.targetYear = year;  }  @Override  public boolean hasNext() {  // 跳过不符合年份的书籍  while (position < books.size()) {  if (books.get(position).getPublishYear() == targetYear) {  return true;  }  position++;  }  return false;  }  @Override  public Book getNext() {  if (hasNext()) {  return books.get(position++);  }  return null;  }  
}  
  • 按条件过滤:在hasNext()中循环查找匹配年份,跳过非目标项

  • 独立职责:遍历逻辑与集合类完全解耦,符合单一职责原则

测试代码
@Test  
public void test_book_year() {  List<Book> books = new ArrayList<>();  books.add(new Book("Java编程思想", "Bruce Eckel", 2018));  books.add(new Book("Effective Java", "Joshua Bloch", 2018));  books.add(new Book("设计模式", "Erich Gamma", 1994));  books.add(new Book("鸟哥的Linux私房菜", "鸟哥", 2010));  BookAggregate bookCollection = new BookYearAggregate(books, 2018);  BookIterator bookIterator = bookCollection.createIterator();  while (bookIterator.hasNext()) {  Book book = bookIterator.getNext();  System.out.println(book.toString());  }  
}  
输出结果
Book{title='Java编程思想', author='Bruce Eckel', publishYear=2018}  
Book{title='Effective Java', author='Joshua Bloch', publishYear=2018}  

长话短说

迭代器模式的优势

  1. 解耦遍历逻辑
    集合类不再关心“如何遍历”,只需提供数据。

  2. 支持多种遍历方式
    新增迭代器即可实现新逻辑,符合开闭原则。

  3. 简化集合接口
    集合类只需提供createIterator()方法,接口更清晰。

  4. 并行遍历
    可以同时创建多个迭代器,独立遍历同一集合。

何时使用迭代器模式?

  • 场景特征
    • 需要以不同方式遍历集合对象(如正序、逆序、过滤)。

    • 不想暴露集合的内部结构(如数组、链表等实现细节)。

    • 需要为集合提供统一的遍历接口。

http://www.xdnf.cn/news/5209.html

相关文章:

  • 【MySQL数据库】--SQLyog创建数据库+python连接
  • 26考研——中央处理器_CPU 的功能和基本结构(5)
  • 机器学习-数据集划分和特征工程
  • Rust 中的 `PartialEq` 和 `Eq`:深入解析与应用
  • 数据库审计如何维护数据完整性:7 种工具和技术
  • 解决Win11下MySQL服务无法开机自启动问题
  • 数巅智能携手北京昇腾创新中心深耕行业大模型应用
  • 卷积神经网络实战(4)代码详解
  • 第二章 如何安装KEIL5和新建工程
  • 【论文解读】| ACL2024 | LANDeRMT:基于语言感知神经元路由的大模型机器翻译微调框架
  • 2025年数维杯C题完整求解思路讲解+代码分享
  • AI星智协脑:智能驱动的高效协作管理平台全解读
  • QT聊天项目DAY10
  • GoWeb开发(基础)
  • web 自动化之 selenium 元素四大操作三大切换等待
  • CSS transition过渡属性
  • NXP iMX8MP ARM 平台多屏幕克隆显示测试
  • 辛格迪客户案例 | 天台山制药仓储管理系统(WMS)项目
  • 普通IT的股票交易成长史--20250509晚复盘
  • 读写锁简介
  • Java——反射
  • DeepSeek致谢腾讯!
  • 热蛋白质组分析(TPP)技术的优劣势探讨
  • EPS三维测图软件
  • CDGP重点知识梳理(82个)
  • 20250509 相对论中的\*\*“无空间”并非真实意义上的虚无,而是时空结构尚未形成\*\*的状态。 仔细解释下这个
  • (undone) MIT6.S081 Lec17 VM for APP 学习笔记
  • LeetCode面试题 17.21 直方图的水量
  • 基于扩展卡尔曼滤波(EKF)目标轨迹算法仿真实例
  • 五一旅游潮涌:数字化如何驱动智慧旅游升级