go实现设计模式系列文章-迭代器模式

153 阅读1分钟

迭代器模式

  迭代器模式的作用是对`集合`中的`元素`进行某种规则的`遍历`(一般是顺序遍历),是不是跟大家经常用的for循环很像? 不过迭代器对其进行了`抽象化`、`通用化`。

  下面看下示例(我们用迭代器模式来实现书架书籍的遍历)。

组成元素

  • 集合接口
package iterator

type Aggregate interface {
        // 生成迭代器
	Iterator() Iterator
}
  • 迭代接口
package iterator

type Iterator interface {
	HasNext() bool
	Next() interface{}
}
  • 集合实现
package iterator

type BookShelf struct {
	books []*Book
}

// 实现接口方法
func (bs *BookShelf) Iterator() Iterator {
	return &BookShelfIterator{
		bookShelf: bs,
	}
}

func (bs *BookShelf) AddBook(book *Book) {
	bs.books = append(bs.books, book)
}
  • 迭代实现
package iterator

type BookShelfIterator struct {
	bookShelf *BookShelf
	idx       int
}

func (bs *BookShelfIterator) SetBookShelf(bookShelf *BookShelf) {
	bs.bookShelf = bookShelf
}
//实现接口方法
func (bs *BookShelfIterator) HasNext() bool {
	return bs.idx < len(bs.bookShelf.books)
}
//实现接口方法
func (bs *BookShelfIterator) Next() interface{} {
	book := bs.bookShelf.books[bs.idx]
	bs.idx++
	return book
}
  • 集合元素
package iterator

type Book struct {
	Name string
}

func (b *Book) GetName() string {
	return b.Name
}

迭代器模式使用

package main

import (
	"dp/iterator"
	"fmt"
)

func main() {
	book1 := &iterator.Book{
		Name: "Chinese",
	}
	book2 := &iterator.Book{
		Name: "English",
	}
	book3 := &iterator.Book{
		Name: "Math",
	}

	// 实例化书架
	bookShelf := &iterator.BookShelf{}
	// 添加书籍
	bookShelf.AddBook(book1)
	bookShelf.AddBook(book2)
	bookShelf.AddBook(book3)
	// 获取迭代器
	iter := bookShelf.Iterator()
	// 迭代打印元素
	for iter.HasNext() {
		book := iter.Next().(*iterator.Book)
		fmt.Println(book.Name)
	}
}

总结

  迭代器的组成元素有`集合接口`、`集合实现`、`迭代接口`、`迭代实现`、`组成元素`这五部分。

  我们看到,在循环迭代部分,代码并不依赖于集合数据的具体实现,无论其是数组实现还是链表或者其他数据结构,我们完全不用考虑。在工程应用中,我们可以进行灵活的扩展、修改,充分利用其灵活性和可扩展性。