Skip to content

Instantly share code, notes, and snippets.

@draganHR
Created October 16, 2019 07:29
Show Gist options
  • Save draganHR/9265c1a8fae58722a3d72d8c49fe8a6a to your computer and use it in GitHub Desktop.
Save draganHR/9265c1a8fae58722a3d72d8c49fe8a6a to your computer and use it in GitHub Desktop.
package observer
type Event interface {
}
type Observer interface {
OnNotify(Event)
}
type Subject struct {
observers map[Observer]struct{}
}
func (o *Subject) Connect(l Observer) {
o.observers[l] = struct{}{}
}
func (o *Subject) Disconnect(l Observer) {
delete(o.observers, l)
}
func (p *Subject) Notify(e Event) {
for o := range p.observers {
o.OnNotify(e)
}
}
package observer
import "fmt"
type eventObserver struct {
id int
}
type EventData struct {
Time string
}
func (o *eventObserver) OnNotify(e Event) {
fmt.Printf("*** Observer %d received: %s\n", o.id, *e.(*EventData))
}
type eventObserver2 struct {
}
func (o *eventObserver2) OnNotify(e Event) {
fmt.Printf("*** Observer2 received: %s\n", *e.(*EventData))
}
func main() {
onSomeEvent := Subject{
observers: map[Observer]struct{}{},
}
// Connect a couple of observers.
onSomeEvent.Connect(&eventObserver{id: 1})
onSomeEvent.Connect(&eventObserver{id: 2})
onSomeEvent.Connect(&eventObserver2{})
// A simple loop publishing the current Unix timestamp to observers.
onSomeEvent.Notify(EventData{"Hello"})
onSomeEvent.Notify(EventData{"Goodbye"})
}
package observer
import (
"github.com/stretchr/testify/assert"
"sort"
"testing"
)
type ExampleData struct {
Message string
}
type exampleObserver struct {
callback func(string)
}
func (o *exampleObserver) OnNotify(e Event) {
o.callback(e.(ExampleData).Message)
}
func TestObserverNotify(t *testing.T) {
results := []string{}
onSomeEvent := Subject{
observers: map[Observer]struct{}{},
}
onSomeEvent.Connect(&exampleObserver{func(msg string) {
results = append(results, msg + " 1")
}})
onSomeEvent.Connect(&exampleObserver{func(msg string) {
results = append(results, msg + " 2")
}})
onSomeEvent.Connect(&exampleObserver{func(msg string) {
results = append(results, msg + " 3")
}})
onSomeEvent.Notify(ExampleData{"Hello"})
sort.Strings(results)
assert.Equal(t, results, []string{"Hello 1", "Hello 2", "Hello 3"})
results = []string{}
onSomeEvent.Notify(ExampleData{"Goodbye"})
sort.Strings(results)
assert.Equal(t, results, []string{"Goodbye 1", "Goodbye 2", "Goodbye 3"})
}
func TestObserverDisconnect(t *testing.T) {
results := []string{}
onSomeEvent := Subject{
observers: map[Observer]struct{}{},
}
observer := &exampleObserver{func(msg string) {
results = append(results, msg)
}}
onSomeEvent.Connect(observer)
onSomeEvent.Notify(ExampleData{"Hello"})
assert.Equal(t, results, []string{"Hello"})
results = []string{}
onSomeEvent.Disconnect(observer)
onSomeEvent.Notify(ExampleData{"Goodbye"})
sort.Strings(results)
assert.Equal(t, results, []string{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment