迭代器模式的英文定义如下:
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
意思是:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。迭代器是为容器服务的,容器是指用来容纳其他对象的对象,例如,Collection集合类型、Set类等。
迭代器模式有以下4个角色:
- 抽象迭代器(Iterator) 角色:该角色负责定义访问和遍历元素的接口;
- 具体迭代器( Concrete Iterator) 角色:该角色实现Iterator接口,完成容器元素的遍历;
- 抽象聚集(Aggregate) 角色:该角色提供创建迭代器角色的接口;
- 具体聚集(Concrete Aggregate) 角色:该角色实现抽象聚集接口,创建出容纳迭代器的对象。
迭代器模式的优点:
- 迭代器模式将数据存储和数据遍历的职责进行分离;
- 迭代器模式简化了遍历容器元素的操作;
- 迭代器模式使不同的容器,具备一个统一的遍历接口;
- 迭代器模式封装了遍历算法,使算法独立于聚集角色,调用者无须知道聚集对象的类型,即使聚集对象的类型发生变化,也不会影响遍历过程。 迭代器模式的缺点:
- 由于迭代器模式将数据存储和数据遍历的职责进行分离,如果增加新的聚合类,同时需要增加与之相对,应的迭代器类,这使得类的个数会成对增加,在某种程度上来说增加了系统的复杂性。
迭代器的应用很广泛,已经发展成为程序开发中最基础的工具类了。在Java语言中,从JDK1.2开始,增加了java.til.lterator 接口,并将Iterator 应用到各个聚集类( Collection)中,如ArrayList、 Vector、Stack、HashSet 等集合类都实现iterator() 方法,返回一个迭代器Iterator,用于对集合中的元素进行遍历。这使我们在项目中无须在独立地写迭代器,直接使用即可,这样既轻松又便捷。 注意:要尽可能地使用编程语言自身提供的迭代器,而非自己写的迭代器。
// 抽象迭代器
type Iterator interface {
Next() interface{}
HasNext() bool
}
// 具体迭代器
type ConcreteIterator struct {
index int
size int
con Aggregate
}
func (c *ConcreteIterator) HasNext() bool {
return c.index < c.size
}
func (c *ConcreteIterator) Next() interface{} {
if c.HasNext() {
res := c.con.GetElement(c.index)
c.index++
return res
}
return nil
}
// 抽象聚集
type Aggregate interface {
Add(obj interface{})
CreateIterator() Iterator
GetElement(index int) interface{}
Size() int
}
// 具体聚集
type ConcreteAggregate struct {
//私有存储容器
docker []interface{}
}
func (c *ConcreteAggregate) Size() int {
return len(c.docker)
}
func (c *ConcreteAggregate) Add(obj interface{}) {
c.docker = append(c.docker,obj)
}
func (c *ConcreteAggregate) CreateIterator() Iterator {
return &ConcreteIterator{
index: 0,
size: c.Size(),
con: c,
}
}
func (c *ConcreteAggregate) GetElement(index int) interface{} {
return c.docker[index]
}
// 定义聚族对象
var (
aggregate Aggregate
iter Iterator
)
aggregate = &ConcreteAggregate{docker: []interface{}{}}
aggregate.Add("java")
aggregate.Add("Golang")
aggregate.Add("Python")
// 遍历
iter = aggregate.CreateIterator()
for iter.HasNext() {
fmt.Println(iter.Next())
}
=== RUN TestConcreteAggregate_Add
java
Golang
Python
--- PASS: TestConcreteAggregate_Add (0.00s)
PASS