在我目前正在工作的应用程序中,我看到了很多观察者。当我更改代码、添加新功能时,这确实给我带来了很多麻烦,因为这些观察者会导致大量副作用。
我想知道需要观察者的场合,以及人们在被诱惑掉入观察者陷阱时的经验或个人经验。
需要您的宝贵经验、 war 故事和思想。请大声喊出来!
最佳答案
我觉得观察者获得不好的评价主要是因为人们将它们与 ActiveRecord 生命周期回调混为一谈。我确实同意很多流行的观点,即生命周期回调很容易被误用,让自己陷入困境,但我个人是观察者的忠实粉丝,因为它们将不是特定模型核心职责的模型类排除在外。这里有一个提示:Rails 的观察者部分受到了面向方面编程的启发——它们是关于横切关注点的。如果您将业务逻辑放在与他们正在观察的模型紧密耦合的观察者中,那么您在 IMO 上做错了。
它们非常适合让模型类保持困惑,例如缓存过期(清扫器)、各种通知、事件流更新、启动后台作业以跟踪自定义分析事件、热缓存等。
我坚决不同意 BlueFish 关于观察者难以正确进行单元测试的观点。这正是将它们与生命周期回调区分开来的最大点:您可以孤立地测试观察者,这样做可以防止您陷入 BlueFish 所指的许多状态和顺序繁重的设计陷阱(我再次认为这更常见)生命周期回调为真)。
这是我的处方:
ActiveRecord::Base.observers.enable
的块形式如果您真的相信有充分的理由为单元测试的一小部分启用观察者,但这可能是误用或设计问题的指标。 after_create
之类的方法)。如果观察者不是其被观察模型的业务逻辑的一部分,它可能不会过多依赖模型实例的状态细节,并且不需要太多的测试设置。如果您有理由相信您的集成测试涵盖了您最关心的内容,那么您通常可以在此处模拟协作者。 这是我的标准样板
spec/support/observers.rb
对于使用 RSpec 的应用程序:RSpec.configure do |config|
# Assure we're testing models in isolation from Observer behavior. Enable
# them explicitly in a block if you need to integrate against an Observer --
# see the documentation for {ActiveModel::ObserverArray}.
config.before do
ActiveRecord::Base.observers.disable :all
end
# Integration tests are full-stack, lack of isolation is by design.
config.before(type: :feature) do
ActiveRecord::Base.observers.enable :all
end
end
和 here is a real-world example我希望这说明了使用观察者的一个很好的例子,并且没有痛苦地测试它。
关于ruby-on-rails - Rails Observers - 何时在 Rails 中使用观察者,何时不使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4866509/