观察员与回调

时间:2009-10-07 13:03:07

标签: ruby-on-rails callback observer-pattern

我想过使用观察者或回调。 什么时候应该使用观察员?

F.e。你可以这样做:

# 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

或者您可以创建一个观察者并让它观察用户何时被创建......

你推荐什么?

3 个答案:

答案 0 :(得分:41)

与米兰诺瓦塔的答案相关的一个非常重要的区别是,ActiveRecord上的回调能够取消被调用的动作以及所有后续回调,而观察者则没有。

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

观察员可能只会观察,他们可能不会介入。

答案 1 :(得分:27)

您可以使用观察员作为解除责任或分配责任的手段。从基本的意义上讲 - 如果你的模型代码太乱了,就开始考虑使用观察者来做一些不必要的行为。观察者的真正力量(至少我认为)在于它们作为模型和其他子系统之间的连接点的能力,其子系统的功能被所有(或某些)其他类使用。假设您决定向应用程序添加IM通知 - 假设您希望收到有关系统中某些(或所有)模型的某些(或所有)CRUD操作的通知。在这种情况下,使用观察者将是理想的 - 您的通知子系统将与您的业务逻辑保持完美分离,并且您的模型不会被不属于其业务的行为所混乱。观察员的另一个好用例是审计子系统。

答案 2 :(得分:9)

回调更短暂:您将其传递给要调用一次的函数。它是API的一部分,你通常无法在不传递回调的情况下调用该函数。这个概念与函数的作用紧密相关。通常,您只能传递一个回调..

示例:运行线程并提供线程终止时调用的回调。

观察者的寿命更长,可随时附加/分离。可以有许多观察者同样的事情,他们可以有不同的生命周期。

示例:在UI中显示模型中的值并从用户输入更新模型。