设计模式系列:一文让你领会“迭代器模式”的用途

基本介绍

通过“迭代”二字我相信大家大概就可以猜出该设计模式的使用场景了。那么大家可能就会有疑问了,遍历还需要设计模式吗?是不是有点过分了?别慌听我慢慢道来。

假设我们的集合是用不同的方式实现的,比如:数组、List、自定义的集合等等……

此时我们想遍历这些集合的话就需要使用不同的方式,并且我们还需要知道集合的内部结构,才能对应的选择适合的遍历方式。这样做的话是不是就有一些繁琐了呢?

为此就衍生出了“迭代器模式”,该模式的设计思想是:提供一种遍历不同集合元素的统一接口,并且无需暴露该集合的内部结构。

“迭代器模式”是属于行为型设计模式的一种。

迭代器模式UML类图

在这里插入图片描述

UML类图讲解

Iterator:迭代器接口。一般使用java内置的接口,该接口提供了遍历时所需的相关方法。
ConcreteIterator:实现了迭代器接口的具体迭代器类。用于迭代集合。
Aggregate:聚合接口。提供了返回迭代器和操作集合的方法。类似于java中的Collection接口。
ConcreteAggregate:实现了聚合接口的具体聚合类。该类含有一个集合并实现了聚合接口定义的方法。
Client:客户端。

注:通过UML类图我们可以发现,迭代器模式将“数据”和“迭代”进行了解耦。在整个结构当中分为两层,其中以Aggregate接口为首的是数据层,以Interator接口为首的是迭代层。

案例讲解

案例:编写一个通用遍历方法,可适用于遍历数组、List等。

迭代器接口使用java.util包下的Iterator接口。

在这里插入图片描述

具体迭代器类

/**
 * 数组迭代器
 */
public class ArrayIterator implements Iterator {

  // 需要遍历的数组
  private String[] array;

  // 遍历的位置
  private int position = 0;

  public ArrayIterator(String[] array) {
    this.array = array;
  }

  /**
   * 是否存在下一个元素
   */
  @Override
  public boolean hasNext() {
    return position < array.length && array[position] != null;
  }

  /**
   * 获取下一个元素
   */
  @Override
  public Object next() {
    return array[position++];
  }
}

/**
 * List迭代器
 */
public class ListIterator implements Iterator {

  // 需要遍历的集合
  private List<String> list;

  // 遍历的位置
  private int position = 0;

  public ListIterator(List<String> list) {
    this.list = list;
  }

  /**
   * 是否存在下一个元素
   */
  @Override
  public boolean hasNext() {
    return position < list.size() && list.get(position) != null;
  }

  /**
   * 获取下一个元素
   */
  @Override
  public Object next() {
    return list.get(position++);
  }
}

聚合接口

/**
 * 聚合接口
 */
public interface Aggregate {

  // 获取一个迭代器
  Iterator createIterator();

}

具体的聚合接口

/**
 * 数组聚合接口
 */
public class ArrayAggregate implements Aggregate {

  // 存放数据的数组
  private String[] array;

  // 记录当前数组对象的个数
  private int num;

  public ArrayAggregate() {
    this.array = new String[3];
  }

  /**
   * 添加元素
   */
  public void add(String value) {
    this.array[num++] = value;
  }

  /**
   * 获取对应的迭代器
   */
  @Override
  public Iterator createIterator() {
    return new ArrayIterator(this.array);
  }
}

/**
 * List聚合接口
 */
public class ListAggregate implements Aggregate {

  // 存放数据的List
  private List<String> list;

  public ListAggregate() {
    this.list = new ArrayList<>();
  }

  /**
   * 添加元素
   */
  public void add(String value) {
    this.list.add(value);
  }

  /**
   * 获取对应的迭代器
   */
  @Override
  public Iterator createIterator() {
    return new ListIterator(this.list);
  }
}

客户端测试类

public class Client {

  public static void main(String[] args) {
    ArrayAggregate arrayAggregate = new ArrayAggregate();
    arrayAggregate.add("小菜鸟");
    arrayAggregate.add("点赞");
    arrayAggregate.add("关注");
    Iterator iterator = arrayAggregate.createIterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}

执行结果

在这里插入图片描述

总结

1、迭代器模式提供一个统一的遍历元素的方法,客户端无需考虑是什么容器存放的元素。

2、客户端遍历集合时只需要获取一个迭代器即可完成遍历,无需知道聚合类的内部结构。

3、通过迭代器模式我们将管理对象集合和遍历对象集合的责任进行了拆分。这样的好处在于聚合对象和迭代器之间互不影响。这样的设计理念是符合单一职责原则的。

4、迭代器模式也是存在相应的问题的,最直观的问题是每个聚合对象都要有一个迭代器,会产生很多个迭代器类,造成类过多。

今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值