迭代器模式

发布时间 2023-08-30 15:19:49作者: INnoVation-V2

迭代器模式

1.简介

迭代器模式(Iterator Pattern),提供了一种顺序访问集合对象中各个元素的方法,同时隐藏了集合对象的内部细节。

使用迭代器模式,可以将遍历集合的逻辑从客户端代码中分离出来,使得客户端只需要与迭代器接口交互,而不需要关心集合的内部实现细节。这有助于提高代码的可维护性和扩展性,因为可以在不影响客户端的情况下修改集合的实现方式。

2.组成

  1. 迭代器接口(Iterator):定义了访问和遍历集合元素的方法,包括获取下一个元素、判断是否还有元素等。
  2. 具体迭代器(Concrete Iterator):实现迭代器接口,提供集合元素的实际遍历实现。
  3. 集合接口(Aggregate):定义创建迭代器的方法,通常包括获取迭代器的方法。
  4. 具体集合(Concrete Aggregate):实现集合接口,提供具体的集合对象。这个对象可以是数组、链表、树等各种集合类型。

3.代码

顺序表

package src

type List struct {
	data []int
	sz   int
}

func NewList(sz int) *List {
	return &List{
		data: make([]int, sz),
		sz:   0,
	}
}

func (l *List) Add(val int) {
	l.data[l.sz] = val
	l.sz++
}

func (l *List) CreateIterator() Iterator {
	return &ListIterator{
		list: l,
		idx:  0}
}

type ListIterator struct {
	list *List
	idx  int
}

func (i *ListIterator) HasNext() bool {
	if i.idx == i.list.sz {
		return false
	}
	return true
}

func (i *ListIterator) Next() (any, bool) {
	if !i.HasNext() {
		return nil, false
	}
	val := i.list.data[i.idx]
	i.idx++
	return val, true
}

链表

package src

type LinkList struct {
	head *Node
}

type Node struct {
	val  interface{}
	next *Node
}

func NewNode(val interface{}) *Node {
	return &Node{
		val: val,
	}
}
func NewLinkList() *LinkList {
	return &LinkList{
		head: NewNode(nil),
	}
}

func (l *LinkList) Add(val interface{}) {
	node := NewNode(val)
	node.next = l.head.next
	l.head.next = node
}

func (l *LinkList) CreateIterator() Iterator {
	return &LinkListIterator{
		head: l.head,
		cur:  l.head}
}

type LinkListIterator struct {
	head *Node
	cur  *Node
}

func (i *LinkListIterator) HasNext() bool {
	if i.cur.next == nil {
		return false
	}
	return true
}

func (i *LinkListIterator) Next() (any, bool) {
	if !i.HasNext() {
		return nil, false
	}
	i.cur = i.cur.next
	return i.cur, true
}

主函数

package src

import (
	"fmt"
	"testing"
)

type Iterator interface {
	HasNext() bool
	Next() (any, bool)
}

type Collection interface {
	CreateIterator() Iterator
}

func visit(iterator Iterator) {
	for iterator.HasNext() {
		val, _ := iterator.Next()
		fmt.Printf("  %v  ", val)
	}
	fmt.Println()
}

func Test_1(t *testing.T) {
	list := NewList(10)
	linkList := NewLinkList()
	for i := 0; i < 10; i++ {
		list.Add(i)
		linkList.Add(i)
	}
	fmt.Println("List:")
	visit(list.CreateIterator())
	fmt.Println("LinkList:")
	visit(linkList.CreateIterator())
}

在上述示例中,一共有两种集合,分别是数组List和链表LinkList

  1. Iterator 是迭代器接口,
  2. ListIteratorLinkListIterator是具体迭代器
  3. Collection 是集合接口
  4. ListLinkList 是具体集合。
  5. 客户端代码通过迭代器遍历集合的元素,而不需要关心集合内部的实现细节。这样,即使集合的实现方式变化,客户端代码也可以保持不变。