本文简要介绍ruby语言中 Observable模块
的用法。
观察者模式(也称为发布/订阅)提供了一种简单的机制,让一个对象在其状态发生变化时通知一组感兴趣的第三方对象。
机制
通知类混合在Observable
模块中,该模块提供了管理相关观察者对象的方法。
可观察对象必须:
-
断言它有
#changed
-
调用
#notify_observers
观察者使用 Observable#add_observer
订阅更新,它还指定通过 notify_observers
调用的方法。 notify_observers
的默认方法是更新。
示例
下面的例子很好地说明了这一点。 Ticker
运行时,会不断收到库存 Price
的 @symbol
。 Warner
是价格的一般观察者,并演示了两个警告器,一个 WarnLow
和一个 WarnHigh
,它们分别在价格低于或高于其设定限制时打印警告。
update
回调允许警告器在不被显式调用的情况下运行。该系统由Ticker
和几个观察者组成,观察者在没有顶级代码干预的情况下履行职责。
请注意,发布者和订阅者(可观察者和观察者)之间的合同未声明或强制执行。 Ticker
发布时间和价格,警告者收到。但是,如果你不能确保你的合同是正确的,那么没有其他东西可以警告你。
require "observer"
class Ticker ### Periodically fetch a stock price.
include Observable
def initialize(symbol)
@symbol = symbol
end
def run
last_price = nil
loop do
price = Price.fetch(@symbol)
print "Current price: #{price}\n"
if price != last_price
changed # notify observers
last_price = price
notify_observers(Time.now, price)
end
sleep 1
end
end
end
class Price ### A mock class to fetch a stock price (60 - 140).
def self.fetch(symbol)
60 + rand(80)
end
end
class Warner ### An abstract observer of Ticker objects.
def initialize(ticker, limit)
@limit = limit
ticker.add_observer(self)
end
end
class WarnLow < Warner
def update(time, price) # callback for observer
if price < @limit
print "--- #{time.to_s}: Price below #@limit: #{price}\n"
end
end
end
class WarnHigh < Warner
def update(time, price) # callback for observer
if price > @limit
print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
end
end
end
ticker = Ticker.new("MSFT")
WarnLow.new(ticker, 80)
WarnHigh.new(ticker, 120)
ticker.run
产生:
Current price: 83 Current price: 75 --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75 Current price: 90 Current price: 134 +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134 Current price: 134 Current price: 112 Current price: 79 --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79
与 procs 一起使用
#notify_observers
方法也可以与 +proc+s 一起使用,方法是将 :call
用作 func
参数。
以下示例说明了 lambda 的使用:
require 'observer'
class Ticker
include Observable
def run
# logic to retrieve the price (here 77.0)
changed
notify_observers(77.0)
end
end
ticker = Ticker.new
warner = ->(price) { puts "New price received: #{price}" }
ticker.add_observer(warner, :call)
ticker.run
相关用法
- Ruby Object.instance_variable_get用法及代码示例
- Ruby Object.display用法及代码示例
- Ruby Object.remove_instance_variable用法及代码示例
- Ruby Object.define_singleton_method用法及代码示例
- Ruby ObjectSpace.memsize_of_all用法及代码示例
- Ruby Object.methods用法及代码示例
- Ruby Object.public_send用法及代码示例
- Ruby ObjectSpace模块用法及代码示例
- Ruby Object.xmp用法及代码示例
- Ruby Object.singleton_methods用法及代码示例
- Ruby Object.enum_for用法及代码示例
- Ruby ObjectSpace.count_symbols用法及代码示例
- Ruby ObjectSpace.define_finalizer用法及代码示例
- Ruby ObjectSpace.count_imemo_objects用法及代码示例
- Ruby Object.freeze用法及代码示例
- Ruby Object.inspect用法及代码示例
- Ruby Object.obj ==用法及代码示例
- Ruby Object.method用法及代码示例
- Ruby Object.DelegateClass用法及代码示例
- Ruby ObjectSpace.allocation_generation用法及代码示例
- Ruby Object.instance_of?用法及代码示例
- Ruby Object.nil?用法及代码示例
- Ruby Object.instance_variable_defined?用法及代码示例
- Ruby ObjectSpace.each_object用法及代码示例
- Ruby ObjectSpace.reachable_objects_from用法及代码示例
注:本文由纯净天空筛选整理自ruby-lang.org大神的英文原创作品 Observable模块。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。