Шаблон итератора — это шаблон поведенческого проектирования, обычно используемый в Java и C#. Этот шаблон в основном используется для упорядоченного доступа к коллекциям (агрегат).
В обычных обстоятельствах нет необходимости использовать его при разработке Golang. И Slice, и Array можно пройти за...range.... Но это не значит, что это не сработает.
Сцены
У меня есть книжная полка (BookShelf), и на ней много книг (Books). Я хочу получить всю информацию о книгах на книжной полке, не раскрывая напрямую внутренние данные BookShelf.
Как мы это реализуем, если применим шаблон итератора?
Очень просто: когда мы хотим получить всю информацию о книге, мы напрямую получаем итератор (Iterator) BookShelf и перемещаемся, чтобы получить информацию о книге, вызывая метод Next() итератора. В обязанности итератора входит просмотр коллекции данных.
интерфейс
Прежде всего, мы знаем, что режим итератора в основном применим к коллекциям данных, поэтому мы можем определить интерфейс Aggregate, который имеет только один метод — вернуть нам итератор.
// 集合接口
type Aggregate interface {
// 返回一个迭代器
GetIterator() Iterator
}
Затем нам также необходимо определить интерфейс итератора (Iterator). Этот интерфейс имеет два метода, а именно HasNext() bool, который определяет, существует ли значение; Next() интерфейс{}, возвращает следующее значение.
// 迭代器接口
type Iterator interface {
// 判断是否还有值
HasNext() bool
// 取下一个值
Next() interface{}
}
выполнить
Далее нам также необходимо определить структуру Book и установить для нее тип книжной полки BookShelf, реализующий интерфейс Aggregate, и BookShelfIterator, реализующий интерфейс Iterator.
// 书
type Book struct {
// 名字
Name string
// 作者
Author string
}
Книга имеет только два поля строкового типа: название названия и автор.
// 书架,一个存放书籍的集合
type BookShelf struct {
books []Book
}
// 书架实现集合接口
func (bs *BookShelf) GetIterator() Iterator {
// 每次都会创建一个新的迭代器,从 index=0 位置开始遍历
return &BookShelfIterator{bookShelf: bs}
}
В BookShelf есть коллекция книг Книги. И реализован метод возврата итератора Iterator интерфейса коллекции (Aggregate).
// 书架迭代器
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).