1、定义
迭代器模式提供一种方法遍历一个集合中的元素,而又不暴露其内部的表示。
2、介绍
- 让我们能遍历集合内的每一个元素,而又不暴露其内部的表示
- 把遍历的任务放在迭代器上,而不是聚合上,这样简化了集合的接口和实现,也让责任各得其所,符合单一职责原则。
3、UML类图
迭代器模式.png角色说明
- Aggregate(集合接口):定义集合的基本功能和创建迭代器的接口,将客户端代码从集合对象的实现解耦
- ConcreteAggregate(具体集合类):实现基本功能,并实例化一个具体迭代器,此迭代器能够遍历该对象集合
- Client(客户端)
- Iterator(迭代器接口):所有具体迭代器都必须实现的接口,包含遍历的一些方法,通常有netx()、hasNext()、remove()方法。
- ConcreteIterator(具体迭代器类):负责实现迭代器接口来实现集合的遍历。
4、实现
4.1 定义集合接口
interface Aggregate<E>{
void add(E e);
//....
IIterator<E> createIterator();
}
4.2 定义迭代器接口
interface IIterator<E> {
E next();
boolean hasNext();
void remove();
}
4.3 具体集合类
这里以菜单为例,菜单结构如下:
class MenuItem {
String name;
String des;
double price;
}
具体集合菜单类,这里用数组来表示菜单集合。
class MenuAggregate implements Aggregate<MenuItem> {
static final int MAX_ITEMS = 10;
MenuItem[] menus = new MenuItem[MAX_ITEMS];
int position = 0;
@Override
public void add(MenuItem menuItem) {
if(position >= MAX_ITEMS) {
throw new IllegalStateException("out of border");
} else {
menus[position] = menuItem;
position++;
}
}
@Override
public IIterator<MenuItem> createIterator() {
return new MenuIterator(menus);
}
}
4.4 具体迭代器
class MenuIterator implements IIterator<MenuItem> {
MenuItem[] menus;
int position = 0;
public MenuIterator(MenuItem[] menus) {
this.menus = menus;
}
@Override
public MenuItem next() {
MenuItem menu = menus[position];
position += 1;
return menu;
}
@Override
public boolean hasNext() {
if (position < menus.length && menus[position] != null) {
return true;
}
return false;
}
@Override
public void remove() {
if(position <= 0) {
throw new IllegalStateException("can't remove item");
}
if(menus[position -1] != null) {
for(int i = position-1;i<menus.length;i++) {
menus[i] = menus[i+1];
}
}
}
}
4.5 客户端调用
Aggregate<MenuItem> aggregate = new MenuAggregate();
aggregate.add(new MenuItem("宫爆鸡丁","川菜",30));
aggregate.add(new MenuItem("水煮鱼","川菜",90));
aggregate.add(new MenuItem("辣子鸡","川菜",32));
IIterator<MenuItem> iIterator = aggregate.createIterator();
while (iIterator.hasNext()) {
System.out.println(iIterator.next());
}
输出结果
MenuItem{name='宫爆鸡丁', des='川菜', price=30.0}
MenuItem{name='水煮鱼', des='川菜', price=90.0}
MenuItem{name='辣子鸡', des='川菜', price=32.0}
5、优点
- 使得集合的遍历与管理相分离,符合单一职则
- 不暴露集合的内部实现
6、缺点
- 类变多了
7、应用场景
容器遍历,如ArrayList
网友评论