Implement the Observer pattern in Go by defining a Subject interface with Attach, Detach, and Notify methods, and a Observer interface with an Update method.
package main
import "fmt"
type Observer interface {
Update(subject Subject)
}
type Subject interface {
Attach(o Observer)
Detach(o Observer)
Notify()
}
type ConcreteSubject struct {
observers []Observer
state int
}
func (s *ConcreteSubject) Attach(o Observer) {
s.observers = append(s.observers, o)
}
func (s *ConcreteSubject) Detach(o Observer) {
for i, obs := range s.observers {
if obs == o {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
func (s *ConcreteSubject) Notify() {
for _, obs := range s.observers {
obs.Update(s)
}
}
func (s *ConcreteSubject) SetState(state int) {
s.state = state
s.Notify()
}
func (s *ConcreteSubject) GetState() int {
return s.state
}
type ConcreteObserver struct {
name string
state int
}
func (o *ConcreteObserver) Update(subject Subject) {
if s, ok := subject.(*ConcreteSubject); ok {
o.state = s.GetState()
fmt.Printf("Observer %s updated: state is now %d\n", o.name, o.state)
}
}
func main() {
subject := &ConcreteSubject{}
o1 := &ConcreteObserver{name: "O1"}
o2 := &ConcreteObserver{name: "O2"}
subject.Attach(o1)
subject.Attach(o2)
subject.SetState(10)
subject.Detach(o1)
subject.SetState(20)
}