Skip to content

迭代器模式

迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种方法来顺序访问一个聚合对象中的各个元素,而无需暴露该对象的内部表示。通过迭代器模式,可以简化集合类的设计,并且允许以统一的方式遍历不同的数据结构,如数组、链表、树等。

迭代器模式的主要角色

  1. Iterator(迭代器接口):声明了用于遍历聚合对象的接口,通常包括hasNext()next()方法。
  2. ConcreteIterator(具体迭代器):实现了 Iterator 接口,同时跟踪当前遍历的进度并返回聚合中的元素。
  3. Aggregate(聚合接口):定义创建相应迭代器对象的接口,通常包含一个createIterator()方法。
  4. ConcreteAggregate(具体聚合类):实现了聚合接口,并返回一个具体的迭代器对象。

在 JavaScript 中的实现

尽管 JavaScript 原生支持迭代协议(如for...of循环和生成器),我们仍然可以通过示例了解如何手动实现迭代器模式。

示例:自定义迭代器

假设我们需要为一个简单的菜单列表实现迭代功能。

javascript
// Iterator(迭代器接口)
class Iterator {
  hasNext() {
    throw new Error("This method should be overridden");
  }

  next() {
    throw new Error("This method should be overridden");
  }
}

// ConcreteIterator(具体迭代器)
class ArrayIterator extends Iterator {
  constructor(items) {
    super();
    this.index = 0;
    this.items = items;
  }

  hasNext() {
    return this.index < this.items.length;
  }

  next() {
    if (this.hasNext()) {
      return this.items[this.index++];
    }
    return null;
  }
}

// Aggregate(聚合接口)
class Menu {
  createIterator() {
    throw new Error("This method should be overridden");
  }
}

// ConcreteAggregate(具体聚合类)
class MenuItemList extends Menu {
  constructor() {
    super();
    this.items = [];
  }

  addItem(item) {
    this.items.push(item);
  }

  createIterator() {
    return new ArrayIterator(this.items);
  }
}

// 使用示例
const menu = new MenuItemList();
menu.addItem("Pizza");
menu.addItem("Pasta");
menu.addItem("Salad");

const iterator = menu.createIterator();

while (iterator.hasNext()) {
  console.log(iterator.next());
}
// 输出:
// Pizza
// Pasta
// Salad

代码解释

  • Iterator(迭代器接口):定义了两个基本方法 hasNext()next()hasNext() 方法用于检查是否还有下一个元素,next() 方法用于获取下一个元素。
  • ArrayIterator(具体迭代器):实现了 Iterator 接口,维护了一个指向当前元素的索引,并提供了实际的遍历逻辑。
  • Menu(聚合接口):定义了一个 createIterator() 方法,所有具体聚合类都需要实现这个方法来提供相应的迭代器。
  • MenuItemList(具体聚合类):实现了 Menu 接口,并提供了一个方法来添加项目到菜单中。createIterator() 方法返回一个新的 ArrayIterator 实例,该实例可以遍历此菜单的所有项目。

应用场景

迭代器模式适用于以下几种情况:

  • 当需要访问一个复杂的数据结构而不暴露其内部表示时。
  • 当需要支持对同一数据结构使用不同类型的遍历时(例如前序遍历、后序遍历等)。
  • 当希望遍历算法独立于数据结构之外时,以便于修改或扩展遍历方式。

通过使用迭代器模式,可以使客户端代码更加简洁,同时也提高了代码的可维护性和灵活性。此外,它还使得数据结构和遍历机制分离,有助于降低系统的耦合度。

Released under the MIT License.