Use Go channels to decouple producers and consumers, allowing multiple subscribers to receive messages from a single publisher without direct references. Create a Subscriber interface, a Topic struct holding a slice of channels, and a Publish method that iterates over subscribers to send data concurrently.
package main
import (
"fmt"
"sync"
)
type Subscriber interface {
Receive(msg string)
}
type Topic struct {
name string
subscribers []Subscriber
mu sync.RWMutex
}
func (t *Topic) Subscribe(s Subscriber) {
t.mu.Lock()
defer t.mu.Unlock()
t.subscribers = append(t.subscribers, s)
}
func (t *Topic) Publish(msg string) {
t.mu.RLock()
defer t.mu.RUnlock()
for _, s := range t.subscribers {
go s.Receive(msg)
}
}
type Logger struct {
id string
}
func (l *Logger) Receive(msg string) {
fmt.Printf("Logger %s received: %s\n", l.id, msg)
}
func main() {
topic := &Topic{name: "news"}
topic.Subscribe(&Logger{id: "A"})
topic.Subscribe(&Logger{id: "B"})
topic.Publish("Breaking News")
}