-
Notifications
You must be signed in to change notification settings - Fork 46
/
main.go
93 lines (80 loc) · 2.29 KB
/
main.go
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Package main serves as an example application that makes use of the observer pattern.
// Playground: https://play.golang.org/p/cr8jEmDmw0
package main
import (
"fmt"
"time"
)
type (
// Event defines an indication of a point-in-time occurrence.
Event struct {
// Data in this case is a simple int, but the actual
// implementation would depend on the application.
Data int64
}
// Observer defines a standard interface for instances that wish to list for
// the occurrence of a specific event.
Observer interface {
// OnNotify allows an event to be "published" to interface implementations.
// In the "real world", error handling would likely be implemented.
OnNotify(Event)
}
// Notifier is the instance being observed. Publisher is perhaps another decent
// name, but naming things is hard.
Notifier interface {
// Register allows an instance to register itself to listen/observe
// events.
Register(Observer)
// Deregister allows an instance to remove itself from the collection
// of observers/listeners.
Deregister(Observer)
// Notify publishes new events to listeners. The method is not
// absolutely necessary, as each implementation could define this itself
// without losing functionality.
Notify(Event)
}
)
type (
eventObserver struct {
id int
}
eventNotifier struct {
// Using a map with an empty struct allows us to keep the observers
// unique while still keeping memory usage relatively low.
observers map[Observer]struct{}
}
)
func (o *eventObserver) OnNotify(e Event) {
fmt.Printf("*** Observer %d received: %d\n", o.id, e.Data)
}
func (o *eventNotifier) Register(l Observer) {
o.observers[l] = struct{}{}
}
func (o *eventNotifier) Deregister(l Observer) {
delete(o.observers, l)
}
func (p *eventNotifier) Notify(e Event) {
for o := range p.observers {
o.OnNotify(e)
}
}
func main() {
// Initialize a new Notifier.
n := eventNotifier{
observers: map[Observer]struct{}{},
}
// Register a couple of observers.
n.Register(&eventObserver{id: 1})
n.Register(&eventObserver{id: 2})
// A simple loop publishing the current Unix timestamp to observers.
stop := time.NewTimer(10 * time.Second).C
tick := time.NewTicker(time.Second).C
for {
select {
case <-stop:
return
case t := <-tick:
n.Notify(Event{Data: t.UnixNano()})
}
}
}