Skip to content

Latest commit

 

History

History
124 lines (99 loc) · 3.6 KB

迭代器模式.md

File metadata and controls

124 lines (99 loc) · 3.6 KB

迭代器模式

定义

迭代器模式的英文定义如下:

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