likes
comments
collection
share

【浅谈设计模式】(20):迭代器模式|简单入门

作者站长头像
站长
· 阅读数 4

前言

龙年开工大吉!

迭代器模式,之前在责任链模式中出现过,结合责任链模式完成动态的模块加载。

迭代,就是遍历集合对象,其实也就是for循环,正常我们也很少使用迭代器模式,因为框架都帮我们封装好了。

那迭代器模式、与 for 循环遍历、foreach 遍历有何区别呢?

今天我们就来浅学迭代器模式。

【浅谈设计模式】(20):迭代器模式|简单入门

一、概念

1.1 概念

来看相关概念。

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

回到前面的问题,遍历集合对象的三种方式:

For 循环相对 Iterator 代码更加简洁,一般情况下我们用的也最多,而foreach 底层的实现就是迭代器模式。

那为什么还要用迭代器来遍历容器呢?

原因有如下几点:

  • 1、对于线性结构的遍历,for循环完全足够了,但是在图、树的复杂遍历下,有深度优先、广度优先、前序、后序等多种遍历算法,这些遍历算法不能由我们自己来实现,也不能放到容器中不然会导致代码复杂性;解决的方式就是将遍历操作拆分到迭代器类中,例如对图的遍历,分别创建深度迭代器、广度迭代器两个迭代类;

  • 2、新增一种遍历算法,我们创建一个迭代器类,实现开闭原则。

迭代器模式的使用就是遍历和解耦容器代码。

1.2 结构

迭代器模式主要有如下四个角色:

  • Iterator(抽象迭代器):定义访问和遍历容器元素的接口,通常有 hasNext、next 等方法;

  • Concretelterator(具体迭代器):实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历;

  • Aggregate(抽象聚合):定义新增、修改、删除聚合元素以及创建迭代器对象的接口;

  • ConcreteAggregate(具体聚合):实现抽象聚合,返回一个具体的迭代器实例。

我们可以来分析下聚合和迭代器的概念。

  • 迭代器:

    • 就是控制方,可以控制切换聚合元素的控制器。
    • 将遍历数据的行为从聚合对象中分离出来,封装到迭代器对象中
  • 聚合对象:

    • 聚合对象存储具体元素对象

1.3 优缺点

优点

  • 支持多种遍历方式,只需要实现不同的迭代器,即可实现聚合对象的遍历算法;
  • 降低了聚合对象和迭代器之间的耦合度,使得聚合对象的内部结构可以随意变化而不影响遍历操作。
  • 引入抽象层,符合开闭原则

缺点

  • 新增类的个数,提高系统复杂度

  • 在某些情况下,可能会导致性能问题,因为迭代器模式需要额外的对象来维护遍历状态,可能会增加内存消耗和运行时开销。

  • 对于简单的遍历操作,使用迭代器模式可能显得过于繁琐,不利于代码的简洁性。

二、案例

迭代器案例,就是对象的遍历。

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

// 创建具体的元素类
class Student {
    private String name;
    private String age;

    public Student(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}

// 创建迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}

// 创建具体的迭代器类
class StudentIterator implements Iterator {
    private List<Student> students;
    private int index;

    public StudentIterator(List<Student> students) {
        this.students = students;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        return index < students.size();
    }

    @Override
    public Object next() {
        Student student = students.get(index);
        index++;
        return student;
    }
}

// 创建抽象聚合类
interface Aggregate {
    Iterator createIterator();
}

// 创建具体的聚合类
class StudentCollection implements Aggregate {
    private List<Student> students;

    public StudentCollection() {
        students = new ArrayList<>();
    }

    public void addStudent(Student student) {
        students.add(student);
    }

    @Override
    public Iterator createIterator() {
        return new StudentIterator(students);
    }
}

// 主程序
public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("大毛", "20");
        Student student2 = new Student("二毛", "22");

        StudentCollection studentCollection = new StudentCollection();
        studentCollection.addStudent(student1);
        studentCollection.addStudent(student2);

        Iterator iterator = studentCollection.createIterator();
        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
        }
    }
}

三、小结

迭代器模式适合以下场景:

  1. 当你希望访问一个聚合对象的内容,但又不想暴露其内部结构时,可以使用迭代器模式。
  2. 当你需要对不同类型的聚合对象进行统一的遍历操作时,可以使用迭代器模式。
  3. 当你希望提供多种遍历方式(正向遍历、逆向遍历等)时,可以使用迭代器模式。
  4. 当你希望分离遍历算法和集合对象时,可以使用迭代器模式。
转载自:https://juejin.cn/post/7336092523771314215
评论
请登录