迭代器模式(Iterator Pattern)

迭代器模式(Iterator Pattern)

迭代器模式是一种行为型设计模式,它提供一种方法顺序访问一个集合中的各个元素,而又不暴露集合的内部表示。迭代器模式通过将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素,而无需关心集合的底层实现。

模式结构

  1. 迭代器接口(Iterator)
    定义遍历集合所需的操作,通常包含 hasNext()next() 方法。
  2. 具体迭代器(Concrete Iterator)
    实现迭代器接口,负责遍历集合中的元素。它通常持有一个集合的引用,并跟踪当前的遍历位置。
  3. 集合接口(Collection)
    定义获取迭代器的方法,通常包含一个 iterator() 方法。
  4. 具体集合(Concrete Collection)
    实现集合接口,负责存储和管理元素,并提供获取迭代器的方法。
  5. 客户端(Client)
    通过迭代器接口遍历集合中的元素,而无需关心集合的内部结构。

代码示例

1. 迭代器接口(Iterator)

// 迭代器接口:定义遍历集合所需的操作
interface CourseIterator {
    Boolean hasNext();
    Course next();
}

2. 具体迭代器(Concrete Iterator)

// 具体迭代器:实现迭代器接口
class CourserIteratorImpl implements CourseIterator {
    private final MajorType majorType;
    private final List<Course> courses;
    private int position;

    public CourserIteratorImpl(MajorType majorType, List<Course> courses) {
        this.majorType = majorType;
        this.courses = courses;
    }

    @Override
    public Boolean hasNext() {
        while (position < courses.size()) {
            Course course = courses.get(position);
            if (course.getMajorType().equals(majorType) || majorType.equals(MajorType.ALL)) {
                return true;
            } else {
                position++;
            }
        }
        return false;
    }

    @Override
    public Course next() {
        Course course = courses.get(position);
        position++;
        return course;
    }
}

3. 集合接口(Collection)

// 集合接口:定义获取迭代器的方法
interface CourseCollection {
    void add(Course course);
    void remove(Course course);
    CourseIterator iterator(MajorType majorType);
}

4. 具体集合(Concrete Collection)

// 具体集合:实现集合接口
class CourseCollectionImpl implements CourseCollection {
    private final List<Course> courses;

    public CourseCollectionImpl() {
        courses = new ArrayList<>();
    }

    @Override
    public void add(Course course) {
        courses.add(course);
    }

    @Override
    public void remove(Course course) {
        courses.remove(course);
    }

    @Override
    public CourseIterator iterator(MajorType majorType) {
        return new CourserIteratorImpl(majorType, courses);
    }
}

5.调用示例

public class IteratorPattern {
    public static void main(String[] args) {
        CourseCollection courses = initCollection();

        // 遍历所有课程
        CourseIterator all = courses.iterator(MajorType.ALL);
        while (all.hasNext()) {
            Course course = all.next();
            System.out.println(course);
        }

        System.out.println("\n<----------------------------->\n");

        // 遍历计算机科学课程
        CourseIterator cs = courses.iterator(MajorType.COMPUTER_SCIENCES);
        while (cs.hasNext()) {
            Course course = cs.next();
            System.out.println(course);
        }
    }

    private static CourseCollection initCollection() {
        CourseCollection courses = new CourseCollectionImpl();
        courses.add(new Course("计算机网络", MajorType.COMPUTER_SCIENCES));
        courses.add(new Course("计算机操作系统", MajorType.COMPUTER_SCIENCES));
        courses.add(new Course("计算机组成原理", MajorType.COMPUTER_SCIENCES));
        courses.add(new Course("数据结构与算法", MajorType.COMPUTER_SCIENCES));
        courses.add(new Course("生物化学", MajorType.BIOLOGY_SCIENCES));
        courses.add(new Course("高等数学", MajorType.MATH));
        courses.add(new Course("宏观经济学", MajorType.FINANCE));
        courses.add(new Course("中国通史", MajorType.HISTORY));

        return courses;
    }
}

输出结果

Course{name='计算机网络', majorType=计算机科学与技术}
Course{name='计算机操作系统', majorType=计算机科学与技术}
Course{name='计算机组成原理', majorType=计算机科学与技术}
Course{name='数据结构与算法', majorType=计算机科学与技术}
Course{name='生物化学', majorType=生物科学}
Course{name='高等数学', majorType=数学}
Course{name='宏观经济学', majorType=金融}
Course{name='中国通史', majorType=历史}

<----------------------------->

Course{name='计算机网络', majorType=计算机科学与技术}
Course{name='计算机操作系统', majorType=计算机科学与技术}
Course{name='计算机组成原理', majorType=计算机科学与技术}
Course{name='数据结构与算法', majorType=计算机科学与技术}

应用场景

  1. 隐藏集合的内部结构
    当集合的底层数据结构较为复杂时,可以使用迭代器模式隐藏其内部结构,使得客户端可以透明地访问集合中的元素。
  2. 多种遍历方式
    当需要为集合提供多种遍历方式时,可以使用迭代器模式。不同的迭代器可以实现不同的遍历逻辑。
  3. 简化遍历代码
    当业务逻辑中存在大量的遍历代码时,可以使用迭代器模式将遍历代码抽离到迭代器中,简化原有方法的职责。

在Java中的应用

  • java.util.Iterator
    Java 集合框架中的 Iterator 接口就是迭代器模式的典型应用。ArrayListHashSet 等集合类都提供了 iterator() 方法来获取迭代器。
  • java.util.Scanner
    Scanner 类可以看作是一个迭代器,它允许逐行读取输入流中的数据。
  • java.util.Enumeration
    Enumeration 是 Java 早期提供的迭代器接口,用于遍历集合中的元素。

优缺点

优点

  1. 简化集合的遍历
    迭代器模式将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素。
  2. 支持多种遍历方式
    迭代器模式可以为集合提供多种遍历方式,不同的迭代器可以实现不同的遍历逻辑。
  3. 符合单一职责原则
    迭代器模式将集合的遍历行为分离到迭代器中,符合单一职责原则。

缺点

  1. 增加代码复杂性
    迭代器模式引入了额外的类和接口,增加了代码的复杂性。
  2. 性能开销
    对于某些特殊的集合,使用迭代器进行遍历可能会引入额外的性能开销。

总结

迭代器模式通过将遍历集合的责任交给迭代器对象,使得客户端可以透明地访问集合中的元素,而无需关心集合的内部结构。它适用于需要隐藏集合内部结构、提供多种遍历方式或简化遍历代码的场景。尽管它可能会增加代码的复杂性,但其优点在于提高了代码的灵活性和可维护性。在Java中,迭代器模式广泛应用于集合框架和输入流处理等场景。