Golang与设计模式-Iterator迭代器模式

迭代器模式在Java和C#中常用到的行为型设计模式,这种模式主要用于对于集合(Aggregate)的有序访问。

一般情况下Golang的开发中是不需要使用到的,像Slice跟Array都可以通过for...range...来完成遍历。但不是说一定就用不上哦。

场景

我有一个书架(BookShelf),书架内摆放了很多书籍(Book),我想要不直接暴露BookShelf内部数据的情况下,获取书架上所有的书籍信息。

如果应用上迭代器模式我们该如何实现呢?

很简单,当我们想要获取所有书籍信息时,直接获取BookShelf的迭代器(Iterator),我们通过对迭代器的方法Next()调用来遍历获取书籍信息。迭代器的职责就是遍历数据集合的。

接口

首先,我们知道迭代器模式主要适用于数据集合,那么我们就可以定义一个集合(Aggregate)接口,这个接口只有一个方法,就是返回给我们一个迭代器(Iterator)。

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

然后,我们还需要一个定义一个迭代器(Iterator)接口,这个接口有两个方法,分别是 HasNext()bool,判断是否还有值;Next()interface{},返回下一个值。

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

实现

接下来我们还需要定义一个Book结构体,并分别定于实现了Aggregate接口书架类型BookShelf,以及实现了 Iterator接口的 BookShelfIterator

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

Book只有两个string类型字段,书名Name,作者Author。

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

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

书架BookShelf中有一个书的集合Books。并且实现了集合(Aggregate)接口的 返回迭代器Iterator的方法。

// 书架迭代器
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
}

书架迭代器BookShelfIterator实现 Iterator接口的两个方法。

测试

接下来我们测试一下代码:

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)
	}
}

运行结果:

代码已上传Github:LyonNee/design_patterns_with_go: 基于Golang实现的设计模式代码 (github.com)

猜你喜欢

转载自blog.csdn.net/Lyon_Nee/article/details/119466202