设计模式(行为型设计模式——迭代器模式)
迭代器模式
基本定义
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
模式结构
Aggregate : 抽象聚合角色。定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
ConcreteAggregate:具体聚合角色。实现抽象聚合类,返回一个具体迭代器的实例。
Iterator:迭代器角色。定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
Concretelterator: 具体迭代器角色。实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
代码实现
Aggregate 抽象容器类
public interface Aggregate {
void add(Object object);
Object get(int index);
int getSize();
//获取迭代器
Iterator iterator();
}
ConcreteAggregate 具体容器对象
@Slf4j
public class ConcreteAggregate implements Aggregate {
private Object[] arr;
private int size;
private int index;
//数据长度
private int ARRAY_LENGTH;
public ConcreteAggregate() {
size = 0;
index = 0;
ARRAY_LENGTH = 10;
arr = new Object[ARRAY_LENGTH];
}
@Override
public void add(Object object) {
arr[index++] = object;
size++;
grow();
}
/**
* 容量自动增长
**/
private void grow() {
double percent = new BigDecimal(size).divide(new BigDecimal(ARRAY_LENGTH)).doubleValue();
if(percent > 0.8){
ARRAY_LENGTH *= 2;
if(ARRAY_LENGTH > Integer.MAX_VALUE){
ARRAY_LENGTH = Integer.MAX_VALUE;
}
Object[] newArr = new Object[ARRAY_LENGTH];
System.arraycopy(arr, 0, newArr, 0, size);
arr = newArr;
}
}
@Override
public Object get(int index) {
return arr[index];
}
@Override
public int getSize() {
return size;
}
@Override
public Iterator iterator() {
return new ConcreteIterator(this);
}
}
Iterator:迭代器角色
public interface Iterator {
boolean hasNext();
Object next();
}
ConcreteIterator 具体的迭代器
public class ConcreteIterator implements Iterator {
//迭代器是为了对容器角色遍历,具体的迭代器需要关联容器角色
private Aggregate aggregate;
private int index;
public ConcreteIterator(Aggregate aggregate) {
this.aggregate = aggregate;
}
@Override
public boolean hasNext() {
if(index >= aggregate.getSize()){
return false;
}
return true;
}
@Override
public Object next() {
Object object = aggregate.get(index);
index++;
return object;
}
}
Test 测试类
@Slf4j
public class Test {
public static void main(String[] args) {
Aggregate aggregate = new ConcreteAggregate();
aggregate.add("宋江");
aggregate.add("武松");
Iterator iterator = aggregate.iterator();
log.info("aggregate size {}", aggregate.getSize());
//无须暴露内部表示
while (iterator.hasNext()){
log.info("{}", iterator.next());
}
}
}
输出结果
aggregate size 8
宋江
武松
优点
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 遍历任务交由迭代器完成,迭代器简化了聚合类。
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
- 封装性良好,为遍历不同的聚合结构提供一个统一的接口。
- 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
应用场景
- 需要为聚合对象提供多种遍历方式。
- 需要为遍历不同的聚合结构提供一个统一的接口。
- 访问一个聚合对象的内容而无须暴露其内部细节。
总结
迭代器模式提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示。
将遍历聚合对象中数据的行为提取出来,封装到一个迭代器中,通过专门的迭代器来遍历聚合对象的内部数据,这就是迭代器模式的本质。