2010-09-17 19 views
14

Ten problem jest dość powszechny: obiekt powinien powiadomić wszystkich swoich subskrybentów, gdy wystąpi pewne zdarzenie. W C++ możemy użyć boost::signals lub czegoś innego. Ale jak to zrobić w języku Go? Byłoby miło zobaczyć przykład działającego kodu, w którym kilka obiektów subskrybuje wydawcy i przetwarza powiadomienia.Wzorzec obserwatora w języku Go

Dzięki

Odpowiedz

14

To jest całkiem proste w Go. Użyj kanałów. To jest coś, do czego są stworzeni.

type Publish struct { 
    listeners []chan *Msg 
} 

type Subscriber struct { 
    Channel chan *Msg 
} 

func (p *Publisher) Sub(c chan *Msg) { 
    p.appendListener(c) 
} 

func (p *Publisher) Pub(m *Msg) { 
    for _, c := range p.listeners { 
     c <- Msg 
    } 
} 

func (s *Subscriber) ListenOnChannel() { 
    for { 
     data := <-s.Channel 
     //Process data 
    } 
} 

func main() { 
    for _, v := range subscribers { 
     p.Sub(v.Channel) 
     go v.ListenOnChannel() 
    } 
    //Some kind of wait here 
} 

Oczywiście nie jest to dokładnie działająca próbka kodu. Ale jest blisko.

+1

Należy zachować ostrożność podczas blokowania operacji na kanale. –

+0

@MizardX oczywiście, normalnie też będę miał kontrolę nad chan, jak chan bool i użyję select {}, i wyjdę z recv z kanału kontrolnego. Ale to dość banalne i nieco przesadzone dla podstawowego przykładu. – cthom06

+1

@MizardX: czy nie jest tak, jakby powiedzieć "uważaj na arytmetykę wskaźnika" w C? Bycie ostrożnym z kanałami to 90% programowania Go ;-) –

Powiązane problemy