简介
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种方法来顺序访问一个聚合对象中的各个元素,而不暴露该对象的内部表示。迭代器模式让我们能够访问一个聚合对象的元素,而不用关心这个对象的内部结构。
涉及到的主要角色:
迭代器 Iterator
定义访问和遍历元素的接口
具体迭代器 concretelterator
实现迭代器接口,具体实现对聚合对象的遍历
聚合 aggregate
定义创建迭代器对象的接口,也可以是一个接口或者抽象类
具体聚合 concreteAggregate
实现创建具体迭代器的接口,返回一个适用于该聚合对象的具体迭代器
客户端 client
使用迭代器模式的客户端代码
比如有一辆车。。。哦,比如有很多辆车,我们需要遍历,自定义遍历。
Demo
type Iterator interface {
HasNext() bool
Next() interface{}
HasPrev() bool
Prev() interface{}
}
type Aggregate interface {
CreateIterator() Iterator
}
// ConcreteAggregate 具体聚合
type ConcreteAggregate struct {
elements []interface{}
}
func (a *ConcreteAggregate) CreateIterator() Iterator {
return &ConcreteIterator{
aggregate: a,
index: 0, // 遍历是从0开始
lastIndex: len(a.elements) - 1,
}
}
// ConcreteIterator 具体迭代器
type ConcreteIterator struct {
aggregate *ConcreteAggregate
index int
lastIndex int
}
func (i *ConcreteIterator) HasNext() bool {
return i.index < len(i.aggregate.elements)
}
func (i *ConcreteIterator) Next() interface{} {
element := i.aggregate.elements[i.index]
i.index++
return element
}
func (i *ConcreteIterator) HasPrev() bool {
return i.lastIndex >= 0
}
func (i *ConcreteIterator) Prev() interface{} {
element := i.aggregate.elements[i.lastIndex]
i.lastIndex--
return element
}
测试
func TestIterator(t *testing.T) {
aggregate := &ConcreteAggregate{
elements: []interface{}{"BMW", "Benz", "Mazda", "BYD", 1, 2, 3, 4},
}
iterator := aggregate.CreateIterator()
// 正序遍历
for iterator.HasNext() {
element := iterator.Next()
fmt.Println(element)
}
fmt.Println("=================")
// 倒序遍历
for iterator.HasPrev() {
element := iterator.Prev()
fmt.Println(element)
}
}
在这个示例中,Iterator 是迭代器接口,定义了访问和遍历元素的方法。Aggregate 是聚合接口,定义了创建迭代器对象的方法。ConcreteIterator 是具体迭代器,实现了迭代器接口,负责实际的遍历操作。ConcreteAggregate 是具体聚合,实现了聚合接口,负责返回一个适用于该聚合对象的具体迭代器。
客户端通过创建具体的聚合对象,然后通过聚合对象的 CreateIterator 方法获取对应的迭代器,最后通过迭代器遍历聚合元素。这样,迭代器模式使得客户端代码可以通过统一的接口来访问不同类型的聚合对象,而无需关心其内部结构。
作用和场景
很明显,有一个作用就是解耦客户端和具体聚合类,客户端只需要调用正序还是逆序相关逻辑即可。符合设计原则中的依赖倒置和开闭原则。
支持多种聚合类型
当系统中存在多个不同类型的聚合,且它们都实现了相同的聚合接口时,客户端可以无缝地切换和使用不同类型的聚合对象。
迭代器模式适用于需要遍历访问一个聚合对象的元素,但不希望客户端直接暴露或依赖于聚合对象的内部结构。当系统中有多种类型的聚合对象,但希望为客户端提供一种统一的迭代器访问方式时,聚合接口可以起到统一的作用,客户端通过统一的接口获取迭代器。
当迭代器的创建和管理逻辑需要在一个集中的地方进行管理时,通过聚合接口可以将这些逻辑集中到一处,便于维护和管理。
总体而言,迭代器模式适用于需要提供一种统一的、便于扩展的迭代器访问方式,并且希望将客户端与具体聚合类的实现解耦的情况。