定义
迭代器模式是一种行为模式, 提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴漏该对象的内部表示。
简单来讲,for range
UML类图
迭代器模式的主要思想是对集合背后的迭代逻辑提取
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
// 迭代器接口
type IIterator interface {
Value() interface{}
HasNext() bool
Next()
}
// 容器接口
type IAggregate interface {
Iterator() IIterator
}
// 具体容器
type Aggregate struct {
container []interface{} // 容器
}
// 创建一个迭代器,并让迭代器中的容器指针指向当前对象
func (a *Aggregate) Iterator() IIterator {
i := new(Iterator)
i.aggregate = a
return i
}
// 实现迭代器
type Iterator struct {
index int // 当前游标
aggregate *Aggregate // 对应的容器指针
}
// 获取当前迭代元素(从容器中取出当前游标对应的元素)
func (i *Iterator) Value() interface{} {
return i.aggregate.container[i.index]
}
// 判断是否迭代到最后,如果没有,则返回true
func (i *Iterator) HasNext() bool {
return i.index+1 < len(i.aggregate.container)
}
// 将游标指向下一个元素
func (i *Iterator) Next() {
if i.index < len(i.aggregate.container) {
i.index++
}
}
func main() {
// 创建容器,并放入初始化数据
c := &Aggregate{container: []interface{}{1, 2, 3, 4}}
// 获取迭代器
iterator := c.Iterator()
// 迭代遍历数据
for iterator.HasNext() {
fmt.Println(iterator.Value())
iterator.Next()
}
}
|
使用场景
总结
优点:
缺点:
- 增加了系统复杂性,需要添加新的迭代器类
- 性能可能不如直接遍历
思考题: 下面这个是迭代器模式吗,为什么?
UML类图
示例代码
cat iterator.go
1
2
3
4
5
6
7
8
9
10
11
|
type Iterator interface {
Value() interface{}
HasNext() bool
Next()
// Index()
// Next()
// Prev()
// ToBegin()
// ToEnd()
}
|
cat collection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
type ArrayIterator struct {
Index int
Array []interface{}
}
func (a *ArrayIterator) Value() interface{} {
return a.Array[a.Index]
}
func (a *ArrayIterator) HasNext() bool {
return a.Index+1 <= len(a.Array)
}
func (a *ArrayIterator) Next() {
if a.HasNext() {
a.Index++
//atomic.AddInt64(&a.index,1)
}
}
|
cat iterator_test1.go
func TestArrayIterator(t *testing.T) {
// 1. 构建迭代器
array := []interface{}{3, 5, 7, 2, 4, 6}
iterator := ArrayIterator{Array: array}
//iterator := ArrayIterator{array: array}
// 2. 遍历迭代器
for it := iterator; it.HasNext();it.Next() {
num := it.Value()
fmt.Println(num)
}
}
cat iteror_test2.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
type User struct {
name string
age int
sex int // 0未知, 1男, 2女
}
func TestArrayIterator_user(t *testing.T) {
// 1. 构建迭代器
user1 := User{"a", 18, 1}
user2 := User{"b", 20, 2}
array := []interface{}{user1, user2}
//// 排序
//sort.Slice(array, func(i, j int) bool {
// return array[i].(User).age < array[j].(User).age
//})
//// 过滤
//filter(&array, func(u interface{}) bool {
// return u.(User).sex == 0
//})
iterator := ArrayIterator{Array: array}
// 2. 遍历迭代器
for it := iterator; it.HasNext(); it.Next() {
user := it.Value()
fmt.Println(user.(User).age)
}
}
func filter(array *[]interface{}, f func(u interface{}) bool) {
for k, v := range *array {
if !f(v) {
*array = append((*array)[:k], (*array)[k+1:]...)
}
}
fmt.Println(array)
}
|