mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-24 20:56:03 +03:00
finish iterator pattern
This commit is contained in:
parent
eabae2e9b7
commit
6b03c9a4f1
@ -4,8 +4,21 @@
|
||||
|
||||
迭代器模式在各种语言中都有很深入,很广泛的应用,迭代器模式就是,对这种存在于语言中的基本模式的进一步应用。
|
||||
|
||||
迭代器模式中的两个重要的接口:
|
||||
|
||||
迭代器是一种管理数据的方式。
|
||||
```go
|
||||
type Iterator interface {
|
||||
//定义迭代器可以进行的动作
|
||||
Next()
|
||||
//...
|
||||
}
|
||||
|
||||
type IEnumerator interface {
|
||||
//返回一个迭代器接口
|
||||
Iterator() Iterator
|
||||
}
|
||||
```
|
||||
|
||||
迭代器是一种管理数据的方式,往往需要一个管理数据的内在容器/集合/链表/栈等结构,需要注意的是,一般在访问上不实现为链表的访问方式,而使用滑动游标的方式。
|
||||
现实生活中的景区的地图指南就是一个很好的迭代器的例子,地图就是一个迭代器,不论是哪个景区,都能通过一张地图(或者说这个迭代器),让你明白当前景区的景点数,最佳参观顺序等,游客只需要按照迭代器的方式去访问景点即可。
|
||||
|
||||
|
@ -3,55 +3,76 @@ package iterator
|
||||
////////////////////////////////
|
||||
//使用景点例子
|
||||
|
||||
//ITouristMap 游客地图是一个迭代器Iterator,为用户提供当前景区中不同景点的统一访问能力
|
||||
type ITouristMap interface {
|
||||
FirstPot() //首个景点
|
||||
IsLastPot() bool //当前景点是否是最后一个
|
||||
Next() interface{} //下一个景点
|
||||
//Iterator 游客地图是一个迭代器Iterator,为用户提供当前景区中不同景点的统一访问能力
|
||||
type Iterator interface {
|
||||
Reset() //重置
|
||||
FirstPot() IPot //首个景点
|
||||
IsLastPot() bool //当前景点是否是最后一个
|
||||
Next() IPot //下一个景点
|
||||
}
|
||||
|
||||
//IScenicArea 是一个针对景区的Aggregate聚合类型接口,返回一个迭代器接口
|
||||
//IScenicArea 返回一个游客访问接口
|
||||
type IScenicArea interface {
|
||||
Iterator() ITouristMap
|
||||
//IPot 景点对象的接口
|
||||
type IPot interface {
|
||||
Visit() //景点可以参观
|
||||
}
|
||||
|
||||
//ScenicArea 景区包含所有的景点
|
||||
type ScenicArea struct {
|
||||
count int //景点的数量
|
||||
pots []interface{} //景点列表,景区可能一直在开发新的景点,所以景区的数量可能一直在增长
|
||||
count int //景点的数量
|
||||
pots []IPot //景点列表,景区可能一直在开发新的景点,所以景区的数量可能一直在增长
|
||||
}
|
||||
|
||||
//Iterator 通过
|
||||
func (s *ScenicArea) Iterator() ITouristMap {
|
||||
return &ScenicAreaPotsMap{
|
||||
numbers: n,
|
||||
next: n.start,
|
||||
//PotsIterator 实现景区景点迭代器的对象
|
||||
//PotsIterator 该对象的目的就是为了隐藏景区本身
|
||||
//PotsIterator 实现为一个游标迭代器
|
||||
type PotsIterator struct {
|
||||
cursor int
|
||||
potsSlice []IPot
|
||||
}
|
||||
|
||||
//Iterator 返回一个接待
|
||||
func (s *ScenicArea) Iterator() Iterator {
|
||||
return &PotsIterator{
|
||||
cursor: 0,
|
||||
potsSlice: s.pots,
|
||||
}
|
||||
}
|
||||
|
||||
//ScenicAreaPotsMap 就是景区提供的迭代器类型,要实现具体的景区景点的迭代访问能力
|
||||
type ScenicAreaPotsMap struct {
|
||||
numbers *Numbers
|
||||
next int
|
||||
//AddPot 添加景点
|
||||
func (s *ScenicArea) AddPot(pots ...IPot) {
|
||||
for i := range pots {
|
||||
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 第一个景点
|
||||
func (i *ScenicAreaPotsMap) FirstPot() {
|
||||
i.next = i.numbers.start
|
||||
func (s *PotsIterator) FirstPot() IPot {
|
||||
return s.potsSlice[0]
|
||||
}
|
||||
|
||||
//IsLastPot 是否是最后一个
|
||||
func (i *ScenicAreaPotsMap) IsLastPot() bool {
|
||||
return i.next > i.numbers.end
|
||||
//IsLastPot 判断游标的位置
|
||||
func (s *PotsIterator) IsLastPot() bool {
|
||||
return s.cursor == -1
|
||||
}
|
||||
|
||||
//Next 去路线上的下一个景点
|
||||
func (i *ScenicAreaPotsMap) Next() interface{} {
|
||||
if !i.IsDone() {
|
||||
next := i.next
|
||||
i.next++
|
||||
return next
|
||||
func (s *PotsIterator) Next() IPot {
|
||||
if s.cursor+1 == len(s.potsSlice) {
|
||||
s.cursor = -1 //设置到最后
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
s.cursor++
|
||||
return s.potsSlice[s.cursor]
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,52 @@
|
||||
package iterator
|
||||
|
||||
func ExampleIterator() {
|
||||
var aggregate Aggregate
|
||||
aggregate = NewNumbers(1, 10)
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
IteratorPrint(aggregate.Iterator())
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
// 6
|
||||
// 7
|
||||
// 8
|
||||
// 9
|
||||
// 10
|
||||
//ChildPot 儿童景点
|
||||
type ChildPot struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (c *ChildPot) Visit() {
|
||||
fmt.Println("i am: ", c.Name)
|
||||
}
|
||||
func TestIterator(t *testing.T) {
|
||||
|
||||
scenicArea := ScenicArea{}
|
||||
|
||||
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
5
go.mod
@ -2,4 +2,7 @@ module github.com/crazybber/go-fucking-algorithm
|
||||
|
||||
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
42
go.sum
@ -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/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=
|
||||
|
Loading…
Reference in New Issue
Block a user