迭代器模式(Iterator)
提供了一种顺序访问聚合对象元素的方法,而无需暴露其内部表示
> 来自【Head First 设计模式】
迭代器模式适用于封装集合内部的复杂数据结构的场景,使用端只需关注容器提供的迭代器,不需要了解其内部实现的细节。实现一个Iterator主要包括:
-
Container 容器:包含一组对象的对象,比如比如数组、链表、树、图、跳表等
-
Iterator 容器迭代器: 迭代器是用来遍历容器的, 包含几个方法:
HasNext()Next()
Go实现迭代器
接着我们一个迭代器的示例来演示Go如何实现
package main
import "fmt"
//1.定义容器迭代器接口
type IIterator interface {
HasNext() bool
Next() interface{}
}
//2.定义容器迭代器具体实现
type Iterator struct {
collection []interface{}
index int
}
func (c *Iterator) HasNext() bool {
return c.index < len(c.collection)
}
func (c *Iterator) Next() interface{} {
if c.HasNext() {
item := c.collection[c.index]
c.index++
return item
}
return nil
}
//3. 定义容器接口
type IContainer interface {
GetIterator() IIterator
}
//4. 定义容器具体实现
type Container struct {
collection []interface{}
}
func (c *Container) GetIterator() IIterator {
return &Iterator{
collection: c.collection,
index: 0,
}
}
func main() {
container := &Container{
collection: []interface{}{1, 2, 3, 4, 5},
}
iterator := container.GetIterator()
for iterator.HasNext() {
item := iterator.Next()
fmt.Println(item)
}
container = &Container{
collection: []interface{}{"a", "b", "c", "d", "e"},
}
iterator = container.GetIterator()
for iterator.HasNext() {
item := iterator.Next()
fmt.Println(item)
}
}
//OUTPUT
//1
//2
//3
//4
//5
//a
//b
//c
//d
//e
上例中,定义了一个容器container实现IContainer,container提供了方法GetIterator来创建对应的迭代器iterator,iterator调用HasNext()实现container的遍历。
优点:
- 容器和迭代器为抽接口,使得操作是基于接口而非具体的实现编程,易于拓展新的容器
- 如上例所示,不同的容器,可以创建多个不同的迭代器,相互之间互不影响
总结
迭代器模式是一种行为型设计模式,封装集合内部的复杂数据结构的场景,隐藏了具体实现细节,职责更加单一,同时使增加新的实现更简单,符合开闭原则。简而言之,使用迭代器模式具有更好封装性、解耦、易拓展的优点。
参考
- 【设计模式之美】
- 【Head First 设计模式】