迭代器模式 (Iterator Pattern)

意图

迭代器模式是一种行为型设计模式,它提供了一种方法来顺序访问集合对象中的元素,而不暴露集合的内部表示。迭代器模式通过引入迭代器对象,允许客户端在不知道集合具体实现的情况下遍历集合中的元素。

问题

在现实世界中,考虑一个购物车应用程序,购物车中包含了各种商品。我们希望能够在不暴露购物车内部实现的情况下,对购物车中的商品进行迭代处理。直接暴露内部实现可能会导致耦合和不必要的复杂性。

解决方案

使用迭代器模式,我们可以定义一个迭代器接口,并创建具体的迭代器类来实现该接口。迭代器对象可以顺序访问集合中的元素,而集合对象只需要提供一个创建迭代器的方法。

模式结构

  1. 迭代器(Iterator):定义了遍历集合的接口,包括获取下一个元素、判断是否还有下一个元素等方法。
  2. 具体迭代器(Concrete Iterator):实现了迭代器接口,具体实现遍历集合的逻辑。
  3. 聚合(Aggregate):定义了创建迭代器的方法。
  4. 具体聚合(Concrete Aggregate):实现了聚合接口,存储集合中的元素,并提供创建具体迭代器的方法。

代码

以下是使用Go语言实现的迭代器模式示例:

package main

import "fmt"

// 迭代器接口
type Iterator interface {
    HasNext() bool
    Next() interface{}
}

// 聚合接口
type Aggregate interface {
    CreateIterator() Iterator
}

// 具体聚合 - 购物车
type ShoppingCart struct {
    items []string
}

func (s *ShoppingCart) AddItem(item string) {
    s.items = append(s.items, item)
}

func (s *ShoppingCart) CreateIterator() Iterator {
    return &ShoppingCartIterator{cart: s, index: 0}
}

// 具体迭代器 - 购物车迭代器
type ShoppingCartIterator struct {
    cart  *ShoppingCart
    index int
}

func (i *ShoppingCartIterator) HasNext() bool {
    return i.index < len(i.cart.items)
}

func (i *ShoppingCartIterator) Next() interface{} {
    item := i.cart.items[i.index]
    i.index++
    return item
}

func main() {
    cart := &ShoppingCart{}
    cart.AddItem("Apple")
    cart.AddItem("Banana")
    cart.AddItem("Cherry")

    iterator := cart.CreateIterator()

    fmt.Println("购物车中的商品:")
    for iterator.HasNext() {
        item := iterator.Next()
        fmt.Println(item)
    }
}

适用场景

  • 需要访问一个集合对象的元素,而不希望暴露集合的内部表示时。
  • 需要支持多种遍历方式时,例如正向遍历和反向遍历。
  • 需要在遍历过程中支持并发操作时。

实现方式

  1. 定义迭代器接口,声明遍历集合的操作。
  2. 创建具体迭代器类,实现迭代器接口,并定义具体的遍历逻辑。
  3. 定义聚合接口,声明创建迭代器的方法。
  4. 创建具体聚合类,实现聚合接口,存储集合中的元素,并提供创建具体迭代器的方法。
  5. 客户端通过迭代器对象遍历集合中的元素,而不需要关心集合的内部实现。

优缺点

优点

  • 遍历集合元素的操作与集合的实现解耦,客户端不需要知道集合的内部结构。
  • 可以为集合提供多种遍历方式,并支持不同的遍历策略。
  • 支持在遍历过程中动态地修改集合。

缺点

  • 可能会引入额外的类,增加系统的复杂性。
  • 如果集合非常大,迭代器的实现可能会增加内存占用。

其他模式的关系

  • 迭代器模式与组合模式(Composite Pattern):组合模式用于将对象组合成树形结构以表示“部分-整体”的层次结构,而迭代器模式用于遍历集合中的元素。迭代器模式可以与组合模式结合使用,以遍历组合模式中的树形结构。
  • 迭代器模式与观察者模式(Observer Pattern):观察者模式用于在对象状态改变时通知观察者,而迭代器模式用于遍历集合中的元素。两者可以结合使用,例如在遍历过程中对元素状态的变化进行观察和处理。
  • 迭代器模式与责任链模式(Chain of Responsibility Pattern):责任链模式用于将请求沿着链传递,而迭代器模式用于遍历集合中的元素。可以结合使用,例如在迭代过程中将请求沿着责任链传递。