概念
提供一种顺序访问一个集合对象的各个元素的方法,而又不暴露该对象的内部表示。
模式的场景和优缺点
使用场景
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示
优点
- 迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
缺点
- 状态模式的使用必然会增加系统类和对象的个数
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
- 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码
代码实现
package main
import (
"fmt"
)
// Aggregate ...
// 创建一个内部对象集合, 集合共用Iterator接口。
type Aggregate interface {
CreateIterator() Iterator
}
// Iterator ...
// 内部对象集合共有的接口操作
type Iterator interface {
First() interface{}
Next() interface{}
IsDone() bool
CurrentItem() interface{}
}
// *******ConcreteAggregate 实现了Aggregate接口*********
// 包含内部对象的集合, 并且构建对象集合对外公共的方法接口Iterator
type ConcreteAggregate struct {
Items []interface{}
}
func (c *ConcreteAggregate) Add(e interface{}) {
c.Items = append(c.Items, e)
}
func (c *ConcreteAggregate) CreateIterator() Iterator {
return &ConcreteIterator{Aggregate: *c}
}
// ***************************************
// ***********ConcreteIterator 实现了 Iterator************
type ConcreteIterator struct {
Aggregate ConcreteAggregate
current int64
}
func (c *ConcreteIterator) First() interface{} {
return c.Aggregate.Items[0]
}
func (c *ConcreteIterator) Next() interface{} {
var ret interface{}
c.current++
if c.current < int64(len(c.Aggregate.Items)) {
ret = c.Aggregate.Items[c.current]
}
return ret
}
func (c *ConcreteIterator) IsDone() bool {
return c.current < int64(len(c.Aggregate.Items))
}
func (c *ConcreteIterator) CurrentItem() interface{} {
return c.Aggregate.Items[c.current]
}
// ***************************************
func main() {
//迭代器模式
// 构建一个数据集合
a := ConcreteAggregate{}
a.Add("a同学")
a.Add("b同学")
// 构建一个数据集合的迭代器
iterator := a.CreateIterator()
for iterator.IsDone() {
fmt.Printf("%v 请买车票", iterator.CurrentItem())
fmt.Println()
iterator.Next()
}
}