The observer pattern in Go

This is a continuation of the common design patterns I found in my old code series, which I started in a previous post.

The observer pattern is a design pattern in which an object (a subject) keeps track of all of its dependents (observers) and notifies them of any state changes.

In Go, the closest example of this pattern are the builtin channels and the use of goroutines:

1
2
3
4
5
6
7
8
9
sub := make(chan interface{})

go func(c <-chan interface{}>) {
    for data := range c {
        fmt.Println(data)
    }
}(sub)

sub <- "Hey there"

Though, for multiple observers to be notified, you need to send the message once for each observer.

Another example is the rxjs lib and accompanying libs for other languages.

And to illustrate how an implementation of this pattern looks like, check the following example:

 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
sub := NewSubject()

sub1 := sub.Subscribe(func (data interface{}) {
    fmt.Println("Sub 1 says", data)
})
sub2 := sub.Subscribe(func (data interface{}) {
    fmt.Println("Sub 2 says", data)
})

sub.Next("Hey there")

sub2.Unsubscribe()

sub.Next("Hey again")

func NewSubject() Subject {
    // ...
}

type Subject interface {
    Subscribe(func(interface{})) Subscription
    Next(interface{})
}

type Subscription interface {
    Unsubscribe()
}

For more design pattern examples, please checkout rolandjitsu/go-design-patterns.