设计模式 迭代器模式

98 阅读2分钟

迭代器模式(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 设计模式】