By: Hunt and Thomas in Ruby Tutorials on 2009年03月03日 [フレーム]
The Observer pattern, also known as Publish/Subscribe, provides a simple mechanism for one object to inform a set of interested third-party objects when its state changes.
In the Ruby implementation, the notifying class mixes in the Observable module, which provides the methods for managing the associated observer objects.
The observers must implement the update method to receive notifications.
The observable object must:
The following example demonstrates this nicely. A Ticker, when run, continually receives the stock Price for its +@symbol+. A Warner is a general observer of the price, and two warners are demonstrated, a WarnLow and a WarnHigh, which print a warning if the price is below or above their set limits, respectively.
The update callback allows the warners to run without being explicitly called. The system is set up with the Ticker and several observers, and the observers do their duty without the top-level code having to interfere.
Note that the contract between publisher and subscriber (observable and observer) is not declared or enforced. The Ticker publishes a time and a price, and the warners receive that. But if you don't ensure that your contracts are correct, nothing else can warn you.
require "observer"
class Ticker ### Periodically fetch a stock price.
include Observable
def initialize(symbol)
@symbol = symbol
end
def run
lastPrice = nil
loop do
price = Price.fetch(@symbol)
print "Current price: #{price}\n"
if price != lastPrice
changed # notify observers
lastPrice = 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 Price.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
Produces:
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
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Most Viewed Articles (in Ruby )
Open and manipulate CSV files in Ruby
dRuby client/server mode sample program
Using Proxy to connect to URLs in Ruby
Reading URL content using Ruby (HTTP)
Latest Articles (in Ruby)
© 2023 Java-samples.com
Tutorial Archive: Data Science React Native Android AJAX ASP.net C C++ C# Cocoa Cloud Computing EJB Errors Java Certification Interview iPhone Javascript JSF JSP Java Beans J2ME JDBC Linux Mac OS X MySQL Perl PHP Python Ruby SAP VB.net EJB Struts Trends WebServices XML Office 365 Hibernate
Latest Tutorials on: Data Science React Native Android AJAX ASP.net C Cocoa C++ C# EJB Errors Java Certification Interview iPhone Javascript JSF JSP Java Beans J2ME JDBC Linux Mac OS X MySQL Perl PHP Python Ruby SAP VB.net EJB Struts Cloud Computing WebServices XML Office 365 Hibernate