1. 设计模式之迭代器模式:封装你的集合迭代逻辑
1.1. 介绍
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
该方式可以提供一种统一的方法来遍历不同的聚合对象。需要遍历一个聚合对象,而又不希望暴露其内部结构时,可以使用该模式。
一般底层架构,中间件使用该模式比较多(eg:jdk 源码中集合类)。项目中如果有比较核心的业务,复杂对象,不想把集合对象结构暴露,可以使用该模式。
优点
1.支持多种遍历方式:不同的迭代器可以定义不同的遍历方式。
2.简化聚合类:聚合类不需要关心遍历逻辑。
3.多遍历支持:可以同时对同一个聚合对象进行多次遍历。
4.扩展性:增加新的聚合类和迭代器类都很方便,无需修改现有代码。
缺点
1.系统复杂性:每增加一个聚合类,就需要增加一个对应的迭代器类,增加了类的数量。
使用建议
1.当需要访问聚合对象内容而不暴露其内部表示时,使用迭代器模式。
2.当需要为聚合对象提供多种遍历方式时,考虑使用迭代器模式。
1.2. 实现及相关代码
假设一个案例,有一个名字集合类,里面包含名字的集合,想要遍历输出名字。
1.2.1. 没使用设计模式方式
案例代码
集合数据对象
public static class NameRepository {
public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};
}
遍历方法
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
String[] names = namesRepository.names;
for(int i = 0 ; i < names.length ; i++){
String name = names[i];
System.out.println("Name : " + name);
}
}
可能会遇到的问题
当业务调整,不得不调整集合数据对象内部结构,例如将 NameRepository 类中 String[] 换成 List<> 时,那么所有遍历的地方都要调整遍历方式,会引发大量地方调整代码,是很大的工作量。
集合类调整
public static class NameRepository {
public List<String> names = new ArrayList<>();
{
names.add("Robert");
names.add("John");
names.add("Julie");
names.add("Lora");
}
}
遍历方式也要跟着调整
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
List<String> names = namesRepository.names;
for(int i = 0 ; i < names.size() ; i++){
String name = names.get(i);
System.out.println("Name : " + name);
}
}
1.2.2. 使用设计模式方式
创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。
IteratorPatternDemo,我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。
创建接口
public interface Iterator {
public boolean hasNext();
public Object next();
}
public interface Container {
public Iterator getIterator();
}
创建实现接口的实体类
public static class NameRepository implements Container {
public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if(index < names.length){
return true;
}
return false;
}
@Override
public Object next() {
if(this.hasNext()){
return names[index++];
}
return null;
}
}
}
迭代器设计模式方式输出打印
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
String name = (String)iter.next();
System.out.println("Name : " + name);
}
}
当 NameRepository 实体类内部结构发生改变时
当集合实体类内部发生改变时,只需要自己调整内部迭代器接口,所有外部调用都不需要调整,大大的减少外部的耦合
public static class NameRepository implements Container {
public List<String> names = new ArrayList<>();
{
names.add("Robert");
names.add("John");
names.add("Julie");
names.add("Lora");
}
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if(index < names.size()){
return true;
}
return false;
}
@Override
public Object next() {
if(this.hasNext()){
return names.get(index++);
}
return null;
}
}
}