finish iterator pattern

This commit is contained in:
Edward 2020-05-03 19:08:54 +08:00
parent eabae2e9b7
commit 6b03c9a4f1
5 changed files with 160 additions and 48 deletions

View File

@ -4,8 +4,21 @@
迭代器模式在各种语言中都有很深入,很广泛的应用,迭代器模式就是,对这种存在于语言中的基本模式的进一步应用。 迭代器模式在各种语言中都有很深入,很广泛的应用,迭代器模式就是,对这种存在于语言中的基本模式的进一步应用。
迭代器模式中的两个重要的接口:
迭代器是一种管理数据的方式。 ```go
type Iterator interface {
//定义迭代器可以进行的动作
Next()
//...
}
type IEnumerator interface {
//返回一个迭代器接口
Iterator() Iterator
}
```
迭代器是一种管理数据的方式,往往需要一个管理数据的内在容器/集合/链表/栈等结构,需要注意的是,一般在访问上不实现为链表的访问方式,而使用滑动游标的方式。
现实生活中的景区的地图指南就是一个很好的迭代器的例子,地图就是一个迭代器,不论是哪个景区,都能通过一张地图(或者说这个迭代器),让你明白当前景区的景点数,最佳参观顺序等,游客只需要按照迭代器的方式去访问景点即可。 现实生活中的景区的地图指南就是一个很好的迭代器的例子,地图就是一个迭代器,不论是哪个景区,都能通过一张地图(或者说这个迭代器),让你明白当前景区的景点数,最佳参观顺序等,游客只需要按照迭代器的方式去访问景点即可。

View File

@ -3,55 +3,76 @@ package iterator
//////////////////////////////// ////////////////////////////////
//使用景点例子 //使用景点例子
//ITouristMap 游客地图是一个迭代器Iterator为用户提供当前景区中不同景点的统一访问能力 //Iterator 游客地图是一个迭代器Iterator为用户提供当前景区中不同景点的统一访问能力
type ITouristMap interface { type Iterator interface {
FirstPot() //首个景点 Reset() //重置
FirstPot() IPot //首个景点
IsLastPot() bool //当前景点是否是最后一个 IsLastPot() bool //当前景点是否是最后一个
Next() interface{} //下一个景点 Next() IPot //下一个景点
} }
//IScenicArea 是一个针对景区的Aggregate聚合类型接口返回一个迭代器接口 //IPot 景点对象的接口
//IScenicArea 返回一个游客访问接口 type IPot interface {
type IScenicArea interface { Visit() //景点可以参观
Iterator() ITouristMap
} }
//ScenicArea 景区包含所有的景点 //ScenicArea 景区包含所有的景点
type ScenicArea struct { type ScenicArea struct {
count int //景点的数量 count int //景点的数量
pots []interface{} //景点列表,景区可能一直在开发新的景点,所以景区的数量可能一直在增长 pots []IPot //景点列表,景区可能一直在开发新的景点,所以景区的数量可能一直在增长
} }
//Iterator 通过 //PotsIterator 实现景区景点迭代器的对象
func (s *ScenicArea) Iterator() ITouristMap { //PotsIterator 该对象的目的就是为了隐藏景区本身
return &ScenicAreaPotsMap{ //PotsIterator 实现为一个游标迭代器
numbers: n, type PotsIterator struct {
next: n.start, cursor int
potsSlice []IPot
}
//Iterator 返回一个接待
func (s *ScenicArea) Iterator() Iterator {
return &PotsIterator{
cursor: 0,
potsSlice: s.pots,
} }
} }
//ScenicAreaPotsMap 就是景区提供的迭代器类型,要实现具体的景区景点的迭代访问能力 //AddPot 添加景点
type ScenicAreaPotsMap struct { func (s *ScenicArea) AddPot(pots ...IPot) {
numbers *Numbers for i := range pots {
next int s.count++
s.pots = append(s.pots, pots[i])
}
}
//PotsCount 添加景点
func (s *ScenicArea) PotsCount() int {
return s.count
}
//Reset 重置
func (s *PotsIterator) Reset() {
s.cursor = 0
} }
//FirstPot 第一个景点 //FirstPot 第一个景点
func (i *ScenicAreaPotsMap) FirstPot() { func (s *PotsIterator) FirstPot() IPot {
i.next = i.numbers.start return s.potsSlice[0]
} }
//IsLastPot 是否是最后一个 //IsLastPot 判断游标的位置
func (i *ScenicAreaPotsMap) IsLastPot() bool { func (s *PotsIterator) IsLastPot() bool {
return i.next > i.numbers.end return s.cursor == -1
} }
//Next 去路线上的下一个景点 //Next 去路线上的下一个景点
func (i *ScenicAreaPotsMap) Next() interface{} { func (s *PotsIterator) Next() IPot {
if !i.IsDone() { if s.cursor+1 == len(s.potsSlice) {
next := i.next s.cursor = -1 //设置到最后
i.next++
return next
}
return nil return nil
} }
s.cursor++
return s.potsSlice[s.cursor]
}

View File

@ -1,19 +1,52 @@
package iterator package iterator
func ExampleIterator() { import (
var aggregate Aggregate "fmt"
aggregate = NewNumbers(1, 10) "testing"
)
IteratorPrint(aggregate.Iterator()) //ChildPot 儿童景点
// Output: type ChildPot struct {
// 1 Name string
// 2 }
// 3
// 4 func (c *ChildPot) Visit() {
// 5 fmt.Println("i am: ", c.Name)
// 6 }
// 7 func TestIterator(t *testing.T) {
// 8
// 9 scenicArea := ScenicArea{}
// 10
scenicArea.AddPot(&ChildPot{Name: "monkey garden"}, &ChildPot{Name: "fairy country"}, &ChildPot{Name: "future space"})
t.Log("pots count:", scenicArea.PotsCount())
potInterator := scenicArea.Iterator()
pot := potInterator.FirstPot()
t.Logf("first pot: %#v\n", pot)
VisitAllPots(potInterator)
t.Log("add a pot", "pot: count", scenicArea.PotsCount())
scenicArea.AddPot(&ChildPot{Name: "virtual world"})
t.Log("pots count:", scenicArea.PotsCount())
//切片变了,要重新获取
potInterator = scenicArea.Iterator()
potInterator.Reset()
VisitAllPots(potInterator)
}
func VisitAllPots(i Iterator) {
for c := i.FirstPot(); !i.IsLastPot(); c = i.Next() {
c.Visit()
fmt.Printf("finish visit pot : %#v\n", c)
}
} }

5
go.mod
View File

@ -2,4 +2,7 @@ module github.com/crazybber/go-fucking-algorithm
go 1.14 go 1.14
require github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 require (
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
go.uber.org/zap v1.15.0
)

42
go.sum
View File

@ -1,2 +1,44 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=