Golang and design pattern - Iterator iterator pattern

The iterator pattern is a behavioral design pattern commonly used in Java and C#. This pattern is mainly used for ordered access to collections (Aggregate).

Under normal circumstances, it is not necessary to use it in the development of Golang. Both Slice and Array can be traversed through for...range.... But that doesn't mean it won't work.

Scenes

I have a bookshelf (BookShelf), and there are many books (Books) in the bookshelf. I want to get all the book information on the bookshelf without directly exposing the internal data of BookShelf.

How do we implement it if we apply the iterator pattern?

Very simple, when we want to get all the book information, we directly get the iterator (Iterator) of BookShelf, and we traverse to get the book information by calling the method Next() of the iterator. The responsibility of the iterator is to traverse the data collection.

interface

First of all, we know that the iterator mode is mainly applicable to data collections, so we can define an Aggregate interface, which has only one method, which is to return an Iterator to us.

// 集合接口
type Aggregate interface {
	// 返回一个迭代器
	GetIterator() Iterator
}

Then, we also need to define an iterator (Iterator) interface, this interface has two methods, namely HasNext () bool, to determine whether there is a value; Next () interface{}, to return the next value.

// 迭代器接口
type Iterator interface {
	// 判断是否还有值
	HasNext() bool
	// 取下一个值
	Next() interface{}
}

accomplish

Next, we also need to define a Book structure, and set it to implement the Aggregate interface bookshelf type BookShelf, and implement the Iterator interface BookShelfIterator respectively

// 书
type Book struct {
	// 名字
	Name string
	// 作者
	Author string
}

Book has only two string type fields, title Name and author Author.

// 书架,一个存放书籍的集合
type BookShelf struct {
	books []Book
}

// 书架实现集合接口
func (bs *BookShelf) GetIterator() Iterator {
	// 每次都会创建一个新的迭代器,从 index=0 位置开始遍历
	return &BookShelfIterator{bookShelf: bs}
}

There is a collection of books Books in BookShelf. And the method of returning the iterator Iterator of the collection (Aggregate) interface is implemented.

// 书架迭代器
type BookShelfIterator struct {
	// 当前遍历位置
	index int
	// 所指向书架
	bookShelf *BookShelf
}

// 书架迭代器实现迭代器接口
func (i *BookShelfIterator) HasNext() bool {
	return i.index < len(i.bookShelf.books)
}

// 书架迭代器实现迭代器接口
func (i *BookShelfIterator) Next() interface{} {
	book := i.bookShelf.books[i.index]
	i.index++

	return book
}

Bookshelf iterator BookShelfIterator implements two methods of Iterator interface.

test

Next, let's test the code:

func main() {
	// 声明一个书架对象,并添加一些书籍
	bookShelf := &BookShelf{
		books: []Book{
			{Name: "以太坊技术详解与实战", Author: "闫莺,郑恺,郭众鑫"},
			{Name: "大话代码架构", Author: "田伟,郎小娇"},
			{Name: "GO语言公链开发实战", Author: "郑东旭,杨明珠,潘盈瑜,翟萌"},
			{Name: "区块链原理、设计与应用", Author: "杨保华,陈昌"},
			{Name: "精通区块链智能合约开发", Author: "熊丽兵"},
			{Name: "C程序设计", Author: "谭浩强"},
		},
	}

	// 获取书架的迭代器
	iterator := bookShelf.GetIterator()

	// 遍历,直到没有下一本书(HasNext == flase)
	for iterator.HasNext() {
		book := iterator.Next().(Book)
		fmt.Printf("书名:%s, 作者:%s \n", book.Name, book.Author)
	}
}

operation result:

The code has been uploaded to Github: LyonNee/design_patterns_with_go: Golang-based design pattern code (github.com)

Guess you like

Origin blog.csdn.net/Lyon_Nee/article/details/119466202