简介
迭代器模式的定义
迭代器模式 (Iterator Pattern) 是一种行为型设计模式,它提供一种顺序访问聚合对象(如列表、集合等)中的元素,而无需暴露聚合对象的内部表示。迭代器模式将遍历逻辑封装在一个迭代器对象中,使得我们可以使用统一的方式遍历不同类型的聚合对象,同时也可以简化客户端代码。
其实在定义中已经将迭代器模式的优点基本上都介绍了,后续结合案例来具体介绍一下优点在实际中的体现。
这个模式在日常的编程中非常的常见,java的很多聚合对象数据结构例如列表,集合都提供了对应的iterator来遍历其中内容。
迭代器模式结构
迭代器模式主要分为四个角色
抽象聚合角色:抽象类,需要定义在聚合角色中迭代器相关接口
具体聚合角色:需要实现聚合角色本身的结构的同时实现抽象聚合角色定义的迭代器相关接口,对外需要提供迭代器对象。
抽象迭代器角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。
具体迭代器角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置,需要针对聚合对象本身结构及具体需求来实现迭代器方法。
案例
用户类
@Data
public class User {
private String name;
private String password;
}
抽象迭代器角色
public interface UserIterator {
//判断是否还有元素
boolean hasNext();
//获取下一个元素
User next();
}
具体迭代器角色
public class UserIteratorImpl implements UserIterator {
private List<User> userList;
private int position=0;
public UserIteratorImpl(List<User> userList) {
this.userList = userList;
}
@Override
public boolean hasNext() {
return position<userList.size();
}
@Override
public User next() {
User user=userList.get(position);
position++;
return user;
}
}
抽象聚合角色
public interface UserAggregate {
void add(User user);
void remove(User user);
//获取迭代器对象
UserIterator getUserIterator();
}
具体聚合角色
public class UserAggregateImpl implements UserAggregate{
private List<User> list = new ArrayList<>();
@Override
public void add(User user) {
list.add(user);
}
@Override
public void remove(User user) {
list.remove(user);
}
@Override
public UserIterator getUserIterator() {
return new UserIteratorImpl(list);
}
}
测试
@Test
public void test()
{
User user1=new User("张三","123456");
User user2=new User("李四","123456");
UserAggregateImpl userAggregate=new UserAggregateImpl();
userAggregate.add(user1);
userAggregate.add(user2);
UserIterator iterator=userAggregate.getUserIterator();
while (iterator.hasNext()){
System.out.println(iterator.next().toString());
}
}
User(name=张三, password=123456)
User(name=李四, password=123456)
总结
从这个案例可以看出迭代器模式的大致构成,但是会发现好像实现的就是在List上面套了层壳,这里是我偷懒了,其实对于较为简单的遍历完全没有必要使用迭代器模式,迭代器模式更多的还是用在复杂结构遍历或者自己实现一些新容器的时候。
结合迭代器的优点来介绍一下一些迭代器我自己理解的实现思路与适合场景
- 简化客户端代码:遍历逻辑封装在迭代器中,客户端不需要知道具体实现。例如当遍历对象内部有嵌套的多个类时,客户端如果想要遍历所有对象就会显得异常麻烦
- 统一遍历接口:在本次例子中只有一个对象,如果有多个对象的话,则可以使多个对象使用相同的遍历方式进行统一遍历
- 支持多种遍历方式:在迭代器内部可以自行实现多种遍历方式,只需要开放对应接口供客户端调用即可
- 解耦聚合对象与遍历操作:迭代器模式将遍历操作从聚合对象中分离出来,使得聚合对象的内部结构不再暴露给客户端,这个很好理解,迭代器返回的是迭代器遍历的指定格式的数据,是可以不和聚合对象内部结构相同的