模式定义
提供一中方法顺序访问一个聚合对象中的各个元素,而又不暴露(稳定)该对象的内部表示
类图
要点总结
- 迭代抽象:访问一个聚合对象的内部而无需暴露它的内部表示
- 迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作
- 迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题
Go语言代码实现
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种顺序访问聚合对象中各个元素的方法,而无需暴露聚合对象的内部表示。
迭代器模式的核心思想是将对集合元素的遍历操作从集合对象中分离出来,交给一个独立的迭代器对象来处理。这样可以使得聚合对象和迭代器对象相互独立,互不依赖,且可以灵活地对集合进行遍历操作。
以下是一个简单的例子来说明迭代器模式的应用:
package main
import "fmt"
// Iterator 迭代器接口
type Iterator interface {
HasNext() bool
Next() string
}
// Aggregate 聚合接口
type Aggregate interface {
CreateIterator() Iterator
}
// ConcreteIterator 具体迭代器
type ConcreteIterator struct {
aggregate *ConcreteAggregate
index int
}
func NewConcreteIterator(aggregate *ConcreteAggregate) *ConcreteIterator {
return &ConcreteIterator{
aggregate: aggregate,
index: 0,
}
}
func (i *ConcreteIterator) HasNext() bool {
if i.index < len(i.aggregate.items) {
return true
}
return false
}
func (i *ConcreteIterator) Next() string {
item := i.aggregate.items[i.index]
i.index++
return item
}
// ConcreteAggregate 具体聚合对象
type ConcreteAggregate struct {
items []string
}
func NewConcreteAggregate() *ConcreteAggregate {
return &ConcreteAggregate{
items: []string{},
}
}
func (a *ConcreteAggregate) CreateIterator() Iterator {
return NewConcreteIterator(a)
}
func (a *ConcreteAggregate) AddItem(item string) {
a.items = append(a.items, item)
}
func main() {
aggregate := NewConcreteAggregate()
aggregate.AddItem("Item 1")
aggregate.AddItem("Item 2")
aggregate.AddItem("Item 3")
iterator := aggregate.CreateIterator()
for iterator.HasNext() {
item := iterator.Next()
fmt.Println(item)
}
}
在上述示例中,我们定义了迭代器接口Iterator和聚合接口Aggregate。迭代器接口声明了遍历集合元素的方法,聚合接口声明了创建迭代器对象的方法。
具体迭代器类ConcreteIterator实现了迭代器接口,它通过持有具体聚合对象ConcreteAggregate来访问集合元素。具体迭代器类维护了一个索引index来追踪当前遍历的位置。
具体聚合对象类ConcreteAggregate实现了聚合接口,它包含一个items数组来存储集合元素。聚合对象类实现了创建迭代器对象的方法,并返回一个具体迭代器对象。
在main函数中,我们创建了具体聚合对象aggregate并添加了几个元素。然后,我们通过调用聚合对象的CreateIterator方法来创建迭代器对象。
最后,我们使用迭代器对象遍历集合元素,并打印每个元素的值。
通过迭代器模式,我们可以将对集合元素的遍历操作与具体聚合对象分离,使得聚合对象可以独立于其内部元素的表示方式进行遍历操作。这提高了代码的灵活性和可维护性。