add two iterator patterns examples

This commit is contained in:
Edward 2020-05-03 19:33:03 +08:00
parent 6b03c9a4f1
commit 4f6f503260
4 changed files with 203 additions and 0 deletions

View File

@ -0,0 +1,91 @@
// Package iterator is an example of the Iterator Pattern.
package iterator
// Iterator provides a iterator interface.
type Iterator interface {
Index() int
Value() interface{}
Has() bool
Next()
Prev()
Reset()
End()
}
// Aggregate provides a collection interface.
type Aggregate interface {
Iterator() Iterator
}
// BookIterator implements the Iterator interface.
type BookIterator struct {
shelf *BookShelf
index int
internal int
}
// Index returns current index
func (i *BookIterator) Index() int {
return i.index
}
// Value returns current value
func (i *BookIterator) Value() interface{} {
return i.shelf.Books[i.index]
}
// Has implementation.
func (i *BookIterator) Has() bool {
if i.internal < 0 || i.internal >= len(i.shelf.Books) {
return false
}
return true
}
// Next goes to the next item.
func (i *BookIterator) Next() {
i.internal++
if i.Has() {
i.index++
}
}
// Prev goes to the previous item.
func (i *BookIterator) Prev() {
i.internal--
if i.Has() {
i.index--
}
}
// Reset resets iterator.
func (i *BookIterator) Reset() {
i.index = 0
i.internal = 0
}
// End goes to the last item.
func (i *BookIterator) End() {
i.index = len(i.shelf.Books) - 1
i.internal = i.index
}
// BookShelf implements the Aggregate interface.
type BookShelf struct {
Books []*Book
}
// Iterator creates and returns the iterator over the collection.
func (b *BookShelf) Iterator() Iterator {
return &BookIterator{shelf: b}
}
// Add adds an item to the collection.
func (b *BookShelf) Add(book *Book) {
b.Books = append(b.Books, book)
}
// Book implements a item of the collection.
type Book struct {
Name string
}

View File

@ -0,0 +1,22 @@
// Package iterator is an example of the Iterator Pattern.
package iterator
import "testing"
func TestIterator(t *testing.T) {
shelf := new(BookShelf)
books := []string{"A", "B", "C", "D", "E", "F"}
for _, book := range books {
shelf.Add(&Book{Name: book})
}
for iterator := shelf.Iterator(); iterator.Has(); iterator.Next() {
index, value := iterator.Index(), iterator.Value().(*Book)
if value.Name != books[index] {
t.Errorf("Expect Book.Name to %s, but %s", books[index], value.Name)
}
}
}

View File

@ -0,0 +1,72 @@
package iterator
import "fmt"
/*
设计思想
1. Iterator结构体
实现Next() HasNext()方法
2. Container容器
容器实现添加 移除Visitor
*/
//创建迭代器
type Iterator struct {
index int
Container
}
func (i *Iterator) Next() Visitor {
fmt.Println(i.index)
visitor := i.list[i.index]
i.index += 1
return visitor
}
func (i *Iterator) HasNext() bool {
if i.index >= len(i.list) {
return false
}
return true
}
//创建容器
type Container struct {
list []Visitor
}
func (c *Container) Add(visitor Visitor) {
c.list = append(c.list, visitor)
}
func (c *Container) Remove(index int) {
if index < 0 || index > len(c.list) {
return
}
c.list = append(c.list[:index], c.list[index+1:]...)
}
//创建Visitor接口
type Visitor interface {
Visit()
}
//创建具体的visitor对象
type Teacher struct{}
type Analysis struct{}
func (t *Teacher) Visit() {
fmt.Println("this is teacher visitor")
}
func (a *Analysis) Visit() {
fmt.Println("this is analysis visitor")
}
//工厂方法创建迭代器
func NewIterator() *Iterator {
return &Iterator{
index: 0,
Container: Container{},
}
}

View File

@ -0,0 +1,18 @@
package iterator
import "testing"
func TestIterator_Next(t *testing.T) {
teacher := new(Teacher)
analysis := new(Analysis)
//迭代器
iterator := NewIterator()
iterator.Add(teacher)
iterator.Add(analysis)
if len(iterator.list) != 2 {
t.Error("期望的count is 2")
}
for iterator.HasNext() {
iterator.Next().Visit()
}
}