迭代器模式是一种行为设计模式,让你能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。
解决什么问题?
- 当集合背后为复杂的数据结构, 且你希望对客户端隐藏其复杂性时 (出于使用便利性或安全性的考虑), 可以使用迭代器模式。
- 如果你希望代码能够遍历不同的甚至是无法预知的数据结构, 可以使用迭代器模式。
优势:
- 单一职责原则。 通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
- 开闭原则。 你可实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
- 你可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态。
- 相似的, 你可以暂停遍历并在需要时继续。
劣势:
- 如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正。
- 对于某些特殊集合, 使用迭代器可能比直接遍历的效率低。
实现步骤:
- 定义迭代器接口
- 定义实体迭代器类,实现迭代器接口
- 定义迭代器工厂接口,用于获取不同的迭代器
- 实体集合类实现迭代器工厂接口
实现代码:
package main
import "fmt"
// 定义迭代器接口
type iterator interface {
getNext() int
hasMore() bool
}
// 定义迭代器工厂接口
type iterable interface {
intoIterator(isForward bool) iterator
}
// 实体集合类
type collection struct {
c []int
}
func (c *collection) get(index int) int {
return c.c[index]
}
func (c *collection) len() int {
return len(c.c)
}
func (c *collection) intoIterator(isForward bool) iterator {
if isForward {
return &forwardIterator{
cur: 0,
c: c,
}
}
return &backwardIterator{
cur: len(c.c) - 1,
c: c,
}
}
// 实体迭代器类
type forwardIterator struct {
cur int
c *collection
}
func (f *forwardIterator) getNext() int {
f.cur += 1
return f.c.get(f.cur - 1)
}
func (f *forwardIterator) hasMore() bool {
if f.cur >= f.c.len() {
return false
}
return true
}
// 实体迭代器类
type backwardIterator struct {
cur int
c *collection
}
func (b *backwardIterator) getNext() int {
b.cur -= 1
return b.c.get(b.cur + 1)
}
func (b *backwardIterator) hasMore() bool {
if b.cur < 0 {
return false
}
return true
}
func main() {
cl := collection{
c: []int{1, 2, 3, 4},
}
fi := cl.intoIterator(true)
for fi.hasMore() {
fmt.Println(fi.getNext())
}
bi := cl.intoIterator(false)
for bi.hasMore() {
fmt.Println(bi.getNext())
}
}
输出:
1
2
3
4
4
3
2
1