迭代器模式
1.简介
迭代器模式(Iterator Pattern),提供了一种顺序访问集合对象中各个元素的方法,同时隐藏了集合对象的内部细节。
使用迭代器模式,可以将遍历集合的逻辑从客户端代码中分离出来,使得客户端只需要与迭代器接口交互,而不需要关心集合的内部实现细节。这有助于提高代码的可维护性和扩展性,因为可以在不影响客户端的情况下修改集合的实现方式。
2.组成
- 迭代器接口(Iterator):定义了访问和遍历集合元素的方法,包括获取下一个元素、判断是否还有元素等。
- 具体迭代器(Concrete Iterator):实现迭代器接口,提供集合元素的实际遍历实现。
- 集合接口(Aggregate):定义创建迭代器的方法,通常包括获取迭代器的方法。
- 具体集合(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
Iterator是迭代器接口,ListIterator和LinkListIterator是具体迭代器Collection是集合接口List和LinkList是具体集合。- 客户端代码通过迭代器遍历集合的元素,而不需要关心集合内部的实现细节。这样,即使集合的实现方式变化,客户端代码也可以保持不变。