单例模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package patterns
import "sync"
type Singleton struct {
Data map[string]string
Id int
}
var (
once sync.Once
singleton *Singleton
idCount int
)
func NewSingleton() *Singleton {
once.Do(func() {
idCount += 1
singleton = &Singleton{
Data: make(map[string]string),
Id: idCount,
}
})
return singleton
}
耗时记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package patterns
import (
"fmt"
"time"
)
func TimeCost(start time.Time, name string) {
fmt.Printf("[%v] cost %v\n", name, time.Since(start))
}
func LongTimeWorking() {
defer TimeCost(time.Now(), "LongTimeWorking")
time.Sleep(time.Millisecond * 500)
}
观察者模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package patterns
import "container/list"
type (
Event struct {
Msg string
}
Notifier interface {
Add(Observer)
Remove(Observer)
Notify(Event)
}
Observer interface {
OnNotify(Event)
}
)
type (
ChatNotifier struct {
observers map[Observer]struct{}
}
ChatObserver struct {
Name string
EventList *list.List
}
ChatEvent struct {
Content string
}
)
func (notifier *ChatNotifier) Add(observer Observer) {
notifier.observers[observer] = struct{}{}
}
func (notifier *ChatNotifier) Remove(observer Observer) {
delete(notifier.observers, observer)
}
func (notifier *ChatNotifier) Notify(e Event) {
for observer := range notifier.observers {
observer.OnNotify(e)
}
}
func (observer *ChatObserver) OnNotify(e Event) {
observer.EventList.PushBack(e)
}
pipeline模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package patterns
func FanIn(input1, input2 <-chan int) <-chan int {
c := make(chan int)
go func() {
for {
c <- <-input1
}
}()
go func() {
for {
c <- <-input2
}
}()
return c
}
func FanIn2(input1, input2 <-chan int) <-chan int {
c := make(chan int)
go func() {
for {
select {
case v := <-input1:
c <- v
case v := <-input2:
c <- v
}
}
}()
return c
}
func FanOut(input <-chan int, outputs []chan<- int, exitChan <-chan int) {
for _, output := range outputs {
go func(out chan<- int) {
for {
select {
case v, ok := <-input:
{
if !ok {
return
}
out <- v
}
case <-exitChan:
{
return
}
}
}
}(output)
}
}
访问者模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package patterns
import (
"encoding/json"
"encoding/xml"
"fmt"
)
type Visitor func(Shape)
type Shape interface {
Accept(Visitor)
}
type Circle struct {
R int
}
type Rectangle struct {
W int
H int
}
func (c *Circle) Accept(v Visitor) {
v(c)
}
func (c *Rectangle) Accept(v Visitor) {
v(c)
}
func JsonVisitor(s Shape) {
bytes, err := json.Marshal(s)
if err == nil {
fmt.Println(string(bytes))
}
}
func XmlVisitor(s Shape) {
bytes, err := xml.Marshal(s)
if err == nil {
fmt.Println(string(bytes))
}
}
代码仓库
https://github.com/yixiaoyang/go-simplelib.git
参考
- https://go.dev/blog/pipelines
- https://refactoringguru.cn/design-patterns/go