迭代器模式 (Iterator Pattern)
意图
迭代器模式是一种行为型设计模式,它提供了一种方法来顺序访问集合对象中的元素,而不暴露集合的内部表示。迭代器模式通过引入迭代器对象,允许客户端在不知道集合具体实现的情况下遍历集合中的元素。
问题
在现实世界中,考虑一个购物车应用程序,购物车中包含了各种商品。我们希望能够在不暴露购物车内部实现的情况下,对购物车中的商品进行迭代处理。直接暴露内部实现可能会导致耦合和不必要的复杂性。
解决方案
使用迭代器模式,我们可以定义一个迭代器接口,并创建具体的迭代器类来实现该接口。迭代器对象可以顺序访问集合中的元素,而集合对象只需要提供一个创建迭代器的方法。
模式结构
- 迭代器(Iterator):定义了遍历集合的接口,包括获取下一个元素、判断是否还有下一个元素等方法。
- 具体迭代器(Concrete Iterator):实现了迭代器接口,具体实现遍历集合的逻辑。
- 聚合(Aggregate):定义了创建迭代器的方法。
- 具体聚合(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)
}
}
适用场景
- 需要访问一个集合对象的元素,而不希望暴露集合的内部表示时。
- 需要支持多种遍历方式时,例如正向遍历和反向遍历。
- 需要在遍历过程中支持并发操作时。
实现方式
- 定义迭代器接口,声明遍历集合的操作。
- 创建具体迭代器类,实现迭代器接口,并定义具体的遍历逻辑。
- 定义聚合接口,声明创建迭代器的方法。
- 创建具体聚合类,实现聚合接口,存储集合中的元素,并提供创建具体迭代器的方法。
- 客户端通过迭代器对象遍历集合中的元素,而不需要关心集合的内部实现。
优缺点
优点:
- 遍历集合元素的操作与集合的实现解耦,客户端不需要知道集合的内部结构。
- 可以为集合提供多种遍历方式,并支持不同的遍历策略。
- 支持在遍历过程中动态地修改集合。
缺点:
- 可能会引入额外的类,增加系统的复杂性。
- 如果集合非常大,迭代器的实现可能会增加内存占用。
其他模式的关系
- 迭代器模式与组合模式(Composite Pattern):组合模式用于将对象组合成树形结构以表示“部分-整体”的层次结构,而迭代器模式用于遍历集合中的元素。迭代器模式可以与组合模式结合使用,以遍历组合模式中的树形结构。
- 迭代器模式与观察者模式(Observer Pattern):观察者模式用于在对象状态改变时通知观察者,而迭代器模式用于遍历集合中的元素。两者可以结合使用,例如在遍历过程中对元素状态的变化进行观察和处理。
- 迭代器模式与责任链模式(Chain of Responsibility Pattern):责任链模式用于将请求沿着链传递,而迭代器模式用于遍历集合中的元素。可以结合使用,例如在迭代过程中将请求沿着责任链传递。