What It Is
The Observer pattern lets one object announce events to many subscribers without knowing who they are. Subscribers register once; from then on, every event reaches all of them automatically.
The publisher depends only on a small subscriber interface — new kinds of listeners appear without one line changing in the publisher.
Example: One Alert, Every Subscriber
The monitor keeps a list of subscribers. When something happens, it notifies the whole list — an email alert and a dashboard, today; a chat message tomorrow, by just subscribing it.
Publish once, deliver to all
One Alert() call, two deliveries. The monitor has no idea what an email or a dashboard is — it only knows things that can be notified.
Output: Go program and captured output
package main
import "fmt"
type Subscriber interface {
Notify(event string)
}
type EmailAlert struct {
addr string
}
func (e EmailAlert) Notify(event string) {
fmt.Println("email to", e.addr+":", event)
}
type Dashboard struct{}
func (Dashboard) Notify(event string) {
fmt.Println("dashboard shows:", event)
}
// The publisher keeps a list and notifies everyone on it.
type Monitor struct {
subscribers []Subscriber
}
func (m *Monitor) Subscribe(s Subscriber) {
m.subscribers = append(m.subscribers, s)
}
func (m *Monitor) Alert(event string) {
for _, s := range m.subscribers {
s.Notify(event)
}
}
func main() {
m := &Monitor{}
m.Subscribe(EmailAlert{addr: "[email protected]"})
m.Subscribe(Dashboard{})
m.Alert("disk almost full")
}
When to Use It
Use it when several parts must react to the same events and the list of reactors changes — UI updates, alerting, cache invalidation, activity feeds.
Skip it when exactly one, fixed receiver exists — call it directly. In concurrent Go programs, consider channels first: they carry events with backpressure and select built in.
Pros and Cons
Pros: publisher and subscribers stay decoupled; subscribers come and go at run time; new reactions need no publisher changes.
Cons: the flow becomes invisible — "who reacts to this?" takes searching; a slow or failing subscriber can stall the notify loop; forgotten unsubscribes leak.