2009-10-07 25 views
32

Pensé en usar observadores o devoluciones de llamada. ¿Qué y cuándo debes usar un observador?Observadores vs. Devolución de llamada

F.e. usted podría hacer lo siguiente:

# 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 

de este modo evitará un observador y se deja ver cuando los usuarios se convierte crearon ...

Lo que Dou Recommened?

Respuesta

9

Una devolución de llamada tiene una vida más corta: la pasa a una función para llamarla una vez. Es parte de la API porque normalmente no se puede llamar a la función sin pasar una devolución de llamada. Este concepto está estrechamente relacionado con lo que hace la función. Por lo general, solo puede pasar una única devolución de llamada ..

Ejemplo: Ejecutar un hilo y dar una devolución de llamada que se invoca cuando finaliza el hilo.

Un observador vive más tiempo y se puede conectar/desmontar en cualquier momento. Puede haber muchos observadores para la misma cosa y pueden tener diferentes tiempos de vida.

Ejemplo: Mostrar valores de un modelo en una interfaz de usuario y actualizar el modelo de la entrada del usuario.

27

Puede usar observadores como un medio de desacoplamiento o distribución de responsabilidades. En el sentido básico: si el código de su modelo se vuelve demasiado desordenado, comience a pensar en usar observadores para algún comportamiento no esencial. El poder real (al menos como yo lo veo) de los observadores radica en su capacidad de servir como un punto de conexión entre sus modelos y algún otro subsistema cuya funcionalidad es utilizada por todas (o algunas) de las otras clases. Supongamos que decide agregar una notificación de MI a su aplicación, digamos que desea que se le notifique sobre algunas (o todas) las acciones de CRUD de algunos (o todos) los modelos de su sistema. En este caso, usar observadores sería ideal: su subsistema de notificación permanecerá perfectamente separado de la lógica de su negocio y sus modelos no se llenarán de un comportamiento que no les incumbe. Otro buen caso de uso para los observadores sería un subsistema de auditoría.

41

Una distinción realmente importante a tener en cuenta, que está relacionada con la respuesta de Milan Novota, es que las devoluciones de llamada en un ActiveRecord tienen la capacidad de cancelar la acción que se llama y todas las devoluciones de llamada posteriores, donde los observadores no lo hacen.

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 

Los observadores solo deben observar, es posible que no intervengan.

+19

Esto ya no es el caso en los rails 3.1 los observadores pueden cancelar la acción de un guardado al devolver falso del before_ * que cancelará la acción y también puede generar una excepción en after_ * para cancelar la acción excepcionalmente. –

+0

Gracias jrizza, tuve un caso similar en el que una falla en uno de los observadores causó que el registro no se guardara, lo cual creo que es un resultado indeseable. –

+2

Sí, es extraño, ya no son observadores, una excepción en un observador hará que la confirmación falle y el usuario recibirá una pantalla de excepción. No tiene sentido para mí. – Amala

Cuestiones relacionadas