「聊设计模式」之迭代器模式(Iterator)

举报
bug菌 发表于 2023/09/26 10:35:02 2023/09/26
【摘要】 在软件开发过程中,我们经常需要遍历集合中的元素,但是如果直接使用集合提供的遍历方法,就会暴露集合底层实现的细节,迭代器模式可以解决这个问题。在本文中,我们将介绍迭代器模式的实现原理、代码示例和测试用例,希望能够帮助读者更好地理解和使用迭代器模式。


🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


大家下午好,我是bug菌,今天我们继续聊设计模式。

前言

  设计模式是软件开发中经验的总结,是一种被反复使用,经过验证的通用解决方案,也是软件技术人员在设计和开发中面对常见问题时的可复用的解决方案。迭代器模式是设计模式中的一种,它可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素。

摘要

  在软件开发过程中,我们经常需要遍历集合中的元素,但是如果直接使用集合提供的遍历方法,就会暴露集合底层实现的细节,迭代器模式可以解决这个问题。在本文中,我们将介绍迭代器模式的实现原理、代码示例和测试用例,希望能够帮助读者更好地理解和使用迭代器模式。

迭代器模式

概述

  迭代器模式是一种行为型设计模式,它可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素。迭代器模式将遍历集合的操作封装到一个迭代器类中,客户端只需要通过迭代器的接口就可以遍历集合中的元素。

结构

迭代器模式有以下几个角色:

  • 抽象聚合类(Aggregate),定义集合对象的接口,封装了集合底层实现的细节,提供了一个可以遍历集合中元素的抽象方法。
  • 具体聚合类(ConcreteAggregate),实现抽象聚合类中的抽象方法,返回一个具体的迭代器。
  • 抽象迭代器类(Iterator),定义遍历集合元素的接口,包括获取下一个元素、判断是否遍历完毕等方法。
  • 具体迭代器类(ConcreteIterator),实现抽象迭代器类中定义的方法,负责遍历集合中的元素。

其迭代器模式UML类图如下:

image.png

迭代器模式优缺点

优点

迭代器模式的优点如下:

  • 封装性好,客户端不需要知道集合内部结构,就可以遍历集合中的元素。
  • 对于不同的集合类型,我们可以定义不同的迭代器,从而实现不同的遍历方法。

缺点

迭代器模式的缺点如下:

  • 迭代器模式增加了类的数量,如果需要遍历的集合比较简单,使用迭代器模式可能会增加不必要的复杂性。
  • 遍历集合时,如果有多个线程同时进行遍历操作,需要对迭代器对象进行同步操作,这会影响程序的性能。

应用场景

迭代器模式的场景包括:

  1. 需要遍历一个聚合对象(如一个列表、数组等)中的元素,但是不想暴露聚合对象的内部结构。

  2. 需要对聚合对象进行多种方式的遍历,如顺序遍历、倒序遍历等。

  3. 需要在遍历过程中实现某些操作,如筛选、过滤等。

  4. 需要在多个不同的聚合对象上进行相同的操作,而不需要关心它们的具体实现。

  5. 需要提供一种统一的遍历接口,以便客户端可以使用相同的方式处理不同的聚合对象。

例子:

  1. 遍历一个网站上的文章列表,以便按照用户的需求进行排序、搜索等操作。

  2. 遍历一个电商平台上的商品列表,以便实现商品的分类、筛选、排序等操作。

  3. 遍历一个音乐播放器中的歌曲列表,以便实现歌曲的随机播放、循环播放等操作。

  4. 遍历一个数据库中的数据表,以便实现数据的增删改查等操作。

模式实现

下面通过Java代码来实现一个简单的迭代器模式:

抽象聚合类

package com.example.javaDesignPattern.iterator;

import java.util.Iterator;

/**
 * @Author bug菌
 * @Date 2023-09-19 22:31
 */
public interface Aggregate {
    public void add(Object obj);

    public void remove(Object obj);

    public Iterator getIterator();
}

具体聚合类

package com.example.javaDesignPattern.iterator;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author bug菌
 * @Date 2023-09-19 22:32
 */
public class ConcreteAggregate implements Aggregate {
    private List<Object> list = new ArrayList<>();

    public void add(Object obj) {
        list.add(obj);
    }

    public void remove(Object obj) {
        list.remove(obj);
    }

    public ConcreteIterator getIterator() {
        return new ConcreteIterator(list);
    }
}

抽象迭代器类

package com.example.javaDesignPattern.iterator;

/**
 * @Author bug菌
 * @Date 2023-09-19 22:32
 */
public interface Iterator {
    public Object next();

    public boolean hasNext();
}

具体迭代器类

package com.example.javaDesignPattern.iterator;

import java.util.List;

/**
 * @Author bug菌
 * @Date 2023-09-19 22:32
 */
public class ConcreteIterator implements Iterator {
    private List<Object> list;
    private int index = 0;

    public ConcreteIterator(List<Object> list) {
        this.list = list;
    }

    public Object next() {
        if (hasNext()) {
            return list.get(index++);
        }
        return null;
    }

    public boolean hasNext() {
        return index < list.size();
    }
}

测试代码

package com.example.javaDesignPattern.iterator;

/**
 * @Author bug菌
 * @Date 2023-09-19 22:33
 */
public class IteratorPatternTest {
    public static void main(String[] args) {
        Aggregate aggregate = new ConcreteAggregate();
        aggregate.add("aaa");
        aggregate.add("bbb");
        aggregate.add("ccc");
        Iterator iterator = aggregate.getIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

测试结果如下:

image.png

测试用例代码解析

  在上面的代码中,我们通过抽象聚合类 Aggregate 和具体聚合类 ConcreteAggregate 封装了集合底层实现的细节,提供了一个可以遍历集合中元素的抽象方法 getIterator()。同时,我们定义了抽象迭代器类 Iterator 和具体迭代器类 ConcreteIterator,它们负责实现遍历集合中元素的具体操作,包括获取下一个元素和判断是否遍历完毕等方法。

  在测试代码中,我们创建了一个具体聚合类的实例 aggregate,并向其中添加了三个元素。然后通过调用 aggregategetIterator() 方法获取一个具体迭代器实例 iterator,并通过 while 循环遍历了集合中的所有元素。

小结

  迭代器模式可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素。它将遍历集合的操作封装到一个迭代器类中,客户端只需要通过迭代器的接口就可以遍历集合中的元素。迭代器模式包含了抽象聚合类、具体聚合类、抽象迭代器类、具体迭代器类等角色,通过这些角色的协作,实现了对集合的遍历操作。迭代器模式的优点包括封装性好、扩展性强,而缺点则是增加了类的数量,可能会增加不必要的复杂性。迭代器模式的应用场景包括需要遍历一个聚合对象中的元素、需要对聚合对象进行多种方式的遍历、需要实现某些操作等。

附录源码

  如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

总结

  迭代器模式是一种用于遍历一个聚合对象(如数组、列表等)中所有元素的设计模式。它通过将遍历集合的操作封装到一个迭代器类中,使得客户端可以通过迭代器的接口来遍历集合中的元素,同时不暴露集合底层实现的细节。

  迭代器模式的优点包括封装性好,能够实现不同的遍历方法,以及可以提供一种统一的遍历接口等。它的缺点则是增加了类的数量,同时在遍历集合时需要对迭代器对象进行同步操作,可能会影响程序的性能。

  迭代器模式适用于需要遍历一个聚合对象中的元素,但不想暴露其内部结构的场景,以及需要对聚合对象进行多种方式的遍历、筛选、过滤等操作的场合。它在遍历列表、数组、数据库等数据结构时十分常见。

  在Java中,我们可以通过定义抽象聚合类和具体聚合类来封装集合的实现,通过定义抽象迭代器类和具体迭代器类来实现遍历集合中元素的具体操作。测试代码中通过创建具体聚合类的实例并向其中添加元素,然后获取迭代器实例并遍历集合中的元素来测试整个迭代器模式的实现。

☀️建议/推荐你

  如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

  我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。