35

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

您可以执行以下操作:

# 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

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

你推荐什么?

4

3 回答 3

45

要记住的一个非常重要的区别与 Milan Novota 的回答有关,即 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

观察者只能观察,不能干预。

于 2011-02-04T00:49:11.510 回答
29

您可以使用观察者作为分离或分配责任的手段。从基本意义上说 - 如果您的模型代码变得太乱,开始考虑使用观察者进行一些不必要的行为。观察者的真正力量(至少在我看来)在于它们能够充当模型和其他子系统之间的连接点,这些子系统的功能被所有(或部分)其他类使用。假设您决定向您的应用程序添加 IM 通知 - 假设您希望收到有关系统中某些(或全部)模型的部分(或全部)CRUD 操作的通知。在这种情况下,使用观察者将是理想的——您的通知子系统将与您的业务逻辑完全分离,并且您的模型不会被与其业务无关的行为弄得一团糟。

于 2009-10-07T16:00:28.293 回答
12

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

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

观察者的寿命更长,并且可以随时附加/分离。同一件事可以有很多观察者,他们可以有不同的生命周期。

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

于 2009-10-07T13:09:32.697 回答