一、简介
迭代器模式(Iterator Design Pattern),也叫作游标模式(Cursor Design Pattern)。
在通过迭代器来遍历集合元素的同时,增加或者删除集合中的元素,有可能会导致某个元素被重复遍历或遍历不到。有两种比较干脆利索的解决方案,来避免出现这种不可预期的运行结果。一种是遍历的时候不允许增删元素,另一种是增删元素之后让遍历报错。第一种解决方案比较难实现,因为很难确定迭代器使用结束的时间点。第二种解决方案更加合理。
二、优点
- 抽象性
- 简化客户端代码
- 支持多种集合类型
- 解耦
三、适用场景
- 遍历不同类型的集合
- 集合实现可能发生变化
- 提供一致的遍历接口
四、UML类图
五、案例
遍历书架上的书并打印书名。
go
package main
import "fmt"
type Iterator interface {
HasNext() bool
Next() interface{}
}
type Book struct {
Title string
}
func NewBook(title string) *Book {
return &Book{Title: title}
}
type BookShelf struct {
BookList []*Book
}
func NewBookShelf() *BookShelf {
return &BookShelf{BookList: []*Book{}}
}
func (bs *BookShelf) AddBook(book *Book) {
bs.BookList = append(bs.BookList, book)
}
type BookIterator struct {
Index int
BookShelf *BookShelf
}
func NewBookIterator(bookShelf *BookShelf) *BookIterator {
return &BookIterator{Index: 0, BookShelf: bookShelf}
}
func (bi *BookIterator) HasNext() bool {
return bi.Index < len(bi.BookShelf.BookList)
}
func (bi *BookIterator) Next() interface{} {
if bi.HasNext() {
book := bi.BookShelf.BookList[bi.Index]
bi.Index += 1
return book
}
return nil
}
func main() {
bookShelf := NewBookShelf()
bookShelf.AddBook(NewBook("book 1"))
bookShelf.AddBook(NewBook("book 2"))
bookShelf.AddBook(NewBook("book 3"))
bookIterator := NewBookIterator(bookShelf)
for bookIterator.HasNext() {
bookObj := bookIterator.Next()
book := bookObj.(*Book)
fmt.Println(book.Title)
}
}