Наблюдатели против Обратных звонков - PullRequest
32 голосов
/ 07 октября 2009

Я думал об использовании наблюдателей или обратных вызовов. Что и когда следует использовать наблюдателя?

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 ]

41 голосов
/ 04 февраля 2011

Следует помнить одно очень важное различие, которое связано с ответом Милана Новоты: обратные вызовы 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

Наблюдатели могут только наблюдать, они не могут вмешиваться.

27 голосов
/ 07 октября 2009

Вы можете использовать наблюдателей как средство разделения или распределения ответственности. В основном смысле - если код вашей модели становится слишком запутанным, подумайте об использовании наблюдателей для какого-то необязательного поведения. Реальная сила (по крайней мере, как мне кажется) наблюдателей заключается в их способности служить связующим звеном между вашими моделями и некоторой другой подсистемой, функциональность которой используется всеми (или некоторыми) другими классами. Допустим, вы решили добавить уведомление IM в свое приложение - скажем, вы хотите получать уведомления о некоторых (или всех) действиях CRUD для некоторых (или всех) моделей в вашей системе. В этом случае использование наблюдателей было бы идеальным вариантом - ваша подсистема уведомлений будет полностью отделена от вашей бизнес-логики, и ваши модели не будут загромождены поведением, которое не является их делом. Другим хорошим вариантом использования для наблюдателей была бы подсистема аудита.

9 голосов
/ 07 октября 2009

Обратный вызов более короток: вы передаете его в функцию, которая будет вызвана один раз. Это часть API, в которой вы обычно не можете вызывать функцию, не передавая обратный вызов. Эта концепция тесно связана с тем, что делает функция. Обычно вы можете передать только один обратный вызов ..

Пример: запуск потока и обратный вызов, который вызывается при завершении потока.

Наблюдатель живет дольше, и его можно прикрепить / отсоединить в любое время. У одной и той же вещи может быть много наблюдателей, и у них может быть разное время жизни.

Пример: отображение значений из модели в пользовательском интерфейсе и обновление модели из пользовательского ввода.

...