设计模式之迭代器模式(上)

迭代器模式
1)概述
1.概念

存储多个成员对象(元素)的类叫聚合类(Aggregate Classes) ,对应的对象称为聚合对象

聚合对象有两个职责,一是存储数据,二是遍历数据。

2.概述

迭代器模式(Iterator Pattern) 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。

3.作用

更加方便地操作聚合对象,可以灵活地为聚合对象增加不同的遍历方法。

可以访问一个聚合对象中的元素但又不需要暴露它的内部结构。

4.迭代器模式+工厂方法模式结构图
5.角色

Iterator(抽象迭代器):定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法。

ConcreteIterator(具体迭代器):实现了抽象迭代器接口,完成对聚合对象的遍历,在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,游标通常是一个表示位置的非负整数。

Aggregate(抽象聚合类):用于存储和管理元素对象,声明createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。

ConcreteAggregate(具体聚合类):实现了在抽象聚合类中声明的createIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。

6.代码实现

抽象迭代器

复制代码
interface Iterator {
  //将游标指向第一个元素
	public void first(); 
	//将游标指向下一个元素
	public void next(); 
	//判断是否存在下一个元素
	public boolean hasNext();
  //获取游标指向的当前元素
	public Object currentItem(); 
}

具体迭代器

复制代码
public class ConcreteIterator implements Iterator {
  //维持一个对具体聚合对象的引用,以便于访问存储在聚合对象中的数据
	private ConcreteAggregate objects; 
	//定义一个游标,用于记录当前访问位置
	private int cursor; 
	public ConcreteIterator(ConcreteAggregate objects) {
		this.objects=objects;
	}
 
	public void first() {  ......  }
		
	public void next() {  ......  }
 
	public boolean hasNext() {  ......  }
	
	public Object currentItem() {  ......  }
}

抽象聚合类

复制代码
interface Aggregate {
	Iterator createIterator();
}

具体聚合类

复制代码
public class ConcreteAggregate implements Aggregate {	
    ......	
    public Iterator createIterator() {
				return new ConcreteIterator(this);
    }
	......
}
7.注意

抽象迭代器接口的设计非常重要,一方面需要充分满足各种遍历操作的要求,尽量为各种遍历方法都提供声明,另一方面又不能包含太多方法,接口中方法太多将给子类的实现带来麻烦。

可以考虑使用抽象类来设计抽象迭代器,在抽象类中为每一个方法提供一个空的默认实现。

2)完整解决方案
1.结构图

AbstractObjectList充当抽象聚合类,ProductList充当具体聚合类,AbstractIterator充当抽象迭代器,ProductIterator充当具体迭代器。

2.代码实现
复制代码
import java.util.*;
 
//抽象聚合类
abstract class AbstractObjectList {
	protected List<Object> objects = new ArrayList<Object>();
 
	public AbstractObjectList(List objects) {
		this.objects = objects;
	}
	
	public void addObject(Object obj) {
		this.objects.add(obj);
	}
	
	public void removeObject(Object obj) {
		this.objects.remove(obj);
	}
	
	public List getObjects() {
		return this.objects;
	}
	
    //声明创建迭代器对象的抽象工厂方法
	public abstract AbstractIterator createIterator();
}
 
//商品数据类:具体聚合类
public class ProductList extends AbstractObjectList {
	public ProductList(List products) {
		super(products);
	}
	
    //实现创建迭代器对象的具体工厂方法
	public AbstractIterator createIterator() {
		return new ProductIterator(this);
	}
} 
 
//抽象迭代器
interface AbstractIterator {
  //移至下一个元素
	public void next(); 
	//判断是否为最后一个元素
	public boolean isLast(); 
	//移至上一个元素
	public void previous(); 
	//判断是否为第一个元素
	public boolean isFirst(); 
	//获取下一个元素
	public Object getNextItem(); 
	//获取上一个元素
	public Object getPreviousItem(); 
}
 
//商品迭代器:具体迭代器
public class ProductIterator implements AbstractIterator {
	private ProductList productList;
	private List products;
	//定义一个游标,用于记录正向遍历的位置
	private int cursor1; 
	//定义一个游标,用于记录逆向遍历的位置
	private int cursor2; 
	
	public ProductIterator(ProductList list) {
	  //获取集合对象
		this.productList = list;
		this.products = list.getObjects(); 
		//设置正向遍历游标的初始值
		cursor1 = 0; 
		//设置逆向遍历游标的初始值
		cursor2 = products.size() -1; 
	}
	
	public void next() {
		if(cursor1 < products.size()) {
			cursor1++;
		}
	}
	
	public boolean isLast() {
		return (cursor1 == products.size());
	}
	
	public void previous() {
		if (cursor2 > -1) {
			cursor2--;
		}
	}
	
	public boolean isFirst() {
		return (cursor2 == -1);
	}
	
	public Object getNextItem() {
		return products.get(cursor1);
	} 
		
	public Object getPreviousItem() {
		return products.get(cursor2);
	} 	
}

客户端类

复制代码
public class Client {
	public static void main(String[] args) {
		List products = new ArrayList();
		products.add("倚天剑");
		products.add("屠龙刀");
		products.add("断肠草");
		products.add("葵花宝典");
		products.add("四十二章经");
			
		AbstractObjectList list;
		AbstractIterator iterator;
		
		list = new ProductList(products); //创建聚合对象
		iterator = list.createIterator();	//创建迭代器对象
		
		System.out.println("正向遍历:");	
		while(!iterator.isLast()) {
			System.out.print(iterator.getNextItem() + ",");
			iterator.next();
		}
		System.out.println();
		System.out.println("-----------------------------");
		System.out.println("逆向遍历:");
		while(!iterator.isFirst()) {
			System.out.print(iterator.getPreviousItem() + ",");
			iterator.previous();
		}
	}
}
相关推荐
维天说12 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane199413 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
杨充13 小时前
11.DDD与战术建模
设计模式·开源·代码规范
杨充13 小时前
12.综合实战图片框架
设计模式·开源·代码规范
噢,我明白了13 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品13 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘13 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记14 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端
糖果店的幽灵14 小时前
langgraph的 MessagesState 解读
java·开发语言·人工智能·windows·langgraph
极光代码工作室15 小时前
基于SpringBoot的在线博客系统
java·springboot·web开发·后端开发