迭代器模式介绍
迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
简单理解:对容器内元素遍历 2.迭代器模式角色划分 迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法:取得下一个元素next(),判断是否遍历结束的方法hasNext(),移除当前对象的方法remove()。 具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。 容器角
色(Aggregate):一般是一个接口,提供一个iterator()方法
角色
抽象聚合类: 定义一个抽象的容器
具体聚合类: 实现上面的抽象类,作为一个容器,用来存放元素,等待迭代
抽象迭代器: 迭代器接口,每个容器下都有一个该迭代器接口的具体实现
具体迭代器: 根据不同的容器,需要定义不同的具体迭代器,定义了游标移动的具体实现
代码结构
├── aggregate.go // 集合接口定义和实现。定义了`NewIterator`、`Data`两个函数
├── aggregate_test.go // 单测
├── go.mod
├── go.sum
└── iterator.go // 迭代器接口定义和实现。
代码解析
聚合接口和定义
type Aggregate[T any] interface {
NewIterator() Iterator[T]
}
接口定义比较简单,NewIterator
方法表示基于当前聚合对象生成一个迭代器
聚合接口的实现
type aggregate[T any] struct {
data []T
}
func NewAggregate[T any](data []T) Aggregate[T] {
return &aggregate[T]{
data: data,
}
}
func (aggr *aggregate[T]) NewIterator() Iterator[T] {
return newIterator[T](aggr)
}
迭代器接口定义和实现
type Iterator[T any] interface {
// First 第一个元素
First() T
// MoveToFirst 移动到第一个元素
MoveToFirst()
// Last 最后一个元素
Last() T
// MoveToLast 移动到最后一个元素
MoveToLast()
// HasNext 是否还有下一个元素
HasNext() bool
// Next 获取下一个元素
Next() T
// Current 获取当前元素
Current() T
// Reverse 翻转
Reverse()
// Empty 集合是否为空
Empty() bool
// Delete 移除当前元素
Delete() T
// Count 元素数量
Count() int
}
迭代器接口定义的方法比较多,但是比较简单,下面看看具体的视线
type iterator[T any] struct {
pointer int // 当前指针
dataArray []any // 集合中的元素,这里定义的是[]any,因为[]T类型不能使用len函数。并且为了不影响集合中的元素,这里重新定义了一个集合
reverse bool // 翻转,表示将当前集合中的元素做180翻转,方便从后往前迭代
count int // 集合中元素数量
}
func newIterator[T any](aggr *aggregate[T]) Iterator[T] {
i := &iterator[T]{
pointer: 0,
}
for _, data := range aggr.data {
i.dataArray = append(i.dataArray, data)
}
i.count = len(i.dataArray)
return i
}
func (i *iterator[T]) First() T {
return i.dataArray[0].(T)
}
func (i *iterator[T]) MoveToFirst() {
i.pointer = 0
}
func (i *iterator[T]) Last() T {
return i.dataArray[i.count-1].(T)
}
func (i *iterator[T]) MoveToLast() {
i.pointer = i.count - 1
}
func (i *iterator[T]) HasNext() bool {
return i.pointer < i.count-1
}
func (i *iterator[T]) Next() T {
if !i.HasNext() {
zeroVal := new(T)
return *zeroVal
}
i.pointer += 1
return i.Current()
}
func (i *iterator[T]) Current() T {
return i.dataArray[i.pointer].(T)
}
func (i *iterator[T]) Reverse() {
newDataAny := make([]any, i.count)
for idx := i.count - 1; idx >= 0; idx-- {
newDataAny[i.count-1-idx] = i.dataArray[idx]
}
i.dataArray = newDataAny
i.pointer = i.count - 1 - i.pointer
i.reverse = !i.reverse
}
func (i *iterator[T]) Empty() bool {
return i.count == 0
}
func (i *iterator[T]) Delete() (deleteData T) {
if i.Empty() {
return
}
newData := make([]any, 0, i.count)
for idx := range i.dataArray {
if idx == i.pointer {
deleteData = i.dataArray[idx].(T)
continue
}
newData = append(newData, i.dataArray[idx])
}
i.count--
i.dataArray = newData
if i.pointer >= i.count {
i.pointer -= 1
}
return
}
func (i *iterator[T]) Count() int {
return i.count
}
源代码:https://github.com/ZBIGBEAR/iterator/tree/main
参考
[1]迭代器模式
[2]golang设计模式之迭代器模式