2009-10-07 14 views
32

Ho pensato di utilizzare osservatori o callback. Cosa e quando si dovrebbe usare un osservatore?Osservatori e callback

F.e. si potrebbe fare seguente:

# User-model 
class User << AR 
    after_create :send_greeting! 

    def send_greeting! 
    UserNotifier.deliver_greeting_message(self) 
    end 

end 

#observer 
class UserNotifier << AR 
    def greeting_message(user) 
    ... 
    end 
end 

o si potrebbe creare un osservatore e lasciarlo guardare quando gli utenti diventa creati ...

Cosa dou si recommened?

risposta

9

Un callback è più breve: lo si passa in una funzione da chiamare una volta. Fa parte dell'API in quanto di solito non è possibile chiamare la funzione senza passare anche una richiamata. Questo concetto è strettamente associato a ciò che fa la funzione. Di solito, è possibile passare solo un singolo callback.

Esempio: esecuzione di un thread e assegnazione di un callback chiamato quando il thread termina.

Un osservatore vive più a lungo e può essere collegato/distaccato in qualsiasi momento. Possono esserci molti osservatori per la stessa cosa e possono avere vite differenti.

Esempio: visualizzazione dei valori da un modello in un'interfaccia utente e aggiornamento del modello dall'input dell'utente.

27

È possibile utilizzare gli osservatori come mezzo di disaccoppiamento o distribuzione di responsabilità. In senso fondamentale: se il codice del tuo modello diventa troppo disordinato, inizia a pensare all'utilizzo di osservatori per un comportamento non essenziale. Il vero potere (almeno come lo vedo io) degli osservatori risiede nella loro capacità di fungere da punto di connessione tra i tuoi modelli e qualche altro sottosistema la cui funzionalità è utilizzata da tutti (o alcuni) dalle altre classi. Supponiamo che tu decida di aggiungere una notifica di messaggistica istantanea alla tua applicazione, ad esempio vuoi essere avvisato di alcune (o tutte) delle azioni CRUD di alcuni (o tutti) dei modelli nel tuo sistema. In questo caso, l'utilizzo di osservatori sarebbe l'ideale: il sottosistema di notifica rimarrà perfettamente separato dalla logica aziendale e i modelli non saranno ingombri di comportamenti non di loro interesse. Un altro buon caso d'uso per gli osservatori sarebbe un sottosistema di auditing.

41

Una distinzione davvero importante da tenere a mente, che è legata alla risposta di Milan Novota, è che i callback su un ActiveRecord hanno la possibilità di annullare l'azione che viene chiamata e tutte le richiamate successive, dove come gli osservatori no.

class Model < ActiveRecord::Base 
    before_update :disallow_bob 

    def disallow_bob 
    return false if model.name == "bob" 
    end 
end 

class ModelObserver < ActiveRecord::Observer 
    def before_update(model) 
    return false if model.name == "mary" 
    end 
end 

m = Model.create(:name => "whatever") 

m.update_attributes(:name => "bob") 
=> false -- name will still be "whatever" in database 

m.update_attributes(:name => "mary") 
=> true -- name will be "mary" in database 

Gli osservatori possono osservare solo che non possono intervenire.

+19

Questo non è più il caso nei binari 3.1 gli osservatori possono annullare l'azione di un salvataggio restituendo false dal precedente_ * che annullerà l'azione e potrebbe anche generare un'eccezione in after_ * per annullare l'azione eccezionalmente. –

+0

Grazie a jrizza, ho avuto un caso simile in cui un fallimento in uno degli osservatori ha fatto sì che il record non venisse salvato, il che credo sia un risultato indesiderato. –

+2

Sì, è strano, non sono più osservatori, un'eccezione in un osservatore causerà il fallimento del commit e l'utente ottiene una schermata di eccezione. Non ha senso per me. – Amala

Problemi correlati