pad.mattdiesel.co.uk

Snippet - Observer Pattern (Go)

Observer Pattern (Go) (Go)


Created 2017-09-19 20:54:52.127470 by Matt.

 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
package main

import (
    "fmt"
)

type IObserver interface {
    Update()
}

type ISubject interface {
    Attach(o IObserver)
    Detach(o IObserver)
    Notify()
}



type Subject struct {
    observers map[IObserver]bool
}
func (s *Subject) Attach(o IObserver) {
    if s.observers == nil {
        s.observers = make(map[IObserver]bool)
    }
    s.observers[o] = true
}
func (s *Subject) Detach(o IObserver) {
    delete(s.observers, o)
}
func (s Subject) Notify() {
    if s.observers == nil { return }
    for o,_ := range s.observers {
        o.Update()
    }
}



type ConcreteSubject struct {
    Subject
    state int
}
func (s *ConcreteSubject) SetState(x int) {
    s.state = x
    s.Notify()
}
func (s ConcreteSubject) GetState() int {
    return s.state
}



type ConcreteObserver struct {
    name string
    subject *ConcreteSubject
    observedState int
}
func (o ConcreteObserver) Update() {
    o.observedState = o.subject.GetState()

    fmt.Println(o.name, ".Update() -> ", o.observedState)
}



func main() {
    var mySubject ConcreteSubject

    myObserverA := ConcreteObserver{"ObserverA",&mySubject,0}
    myObserverB := ConcreteObserver{"ObserverB",&mySubject,0}

    mySubject.Attach(&myObserverA)
    mySubject.Attach(&myObserverB)

    mySubject.SetState(42)
    mySubject.SetState(17)
}