Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Но мы добавили одну тонкость. Не желая следить за малейшими колебаниями цен, мы реализовали модуль
ObserverСначала рассмотрим модуль
DrbObservableObserverВ листинге 20.1 наблюдатель определен как объект, отвечающий на вызов метода update. Сервер добавляет наблюдателей по их просьбе и посылает им уведомления, обращаясь к методу
notify_observersmodule DRbObservable def add_observer(observer) @observer_peers ||= [] unless observer.respond_to? :update raise NameError, "наблюдатель должен отвечать на вызов 'update'" end @observer_peers.push observer end def delete_observer(observer) @observer_peers.delete observer if defined? @observer_peers end def notify_observers(*arg) return unless defined? @observer_peers for i in @observer_peers.dup begin i.update(*arg) rescue delete_observer(i) end end endendСервер (он же канал) в листинге 20.2 эмулирует биржевые котировки с помощью последовательности псевдослучайных чисел (простите мою иронию, но это очень точно соответствует характеру рынка). Символ, идентифицирующий компанию, — всего лишь косметическое украшение, никакого реального смысла в этой программе он не имеет. При каждом изменении цены посылается уведомление всем наблюдателям.
require "drb"require "drb_pbserver"# Генерировать случайные котировки.class MockPrice MIN = 75 RANGE = 50 def initialize(symbol) @price = RANGE / 2 end def price @price += (rand() - 0.5)*RANGE if @price < 0 @price = [email protected] elsif @price >= RANGE @price = 2*RANGE - @price end MIN + @price endendclass Ticker # Периодически получать котировку акций. include DRbObservable def initialize(price_feed) @feed = price_feed Thread.new { run } end def run lastPrice = nil loop do price = @feed.price print "Текущая котировка: #{price}n" if price != lastPrice lastPrice = price notify_observers(Time.now, price) end sleep 1 end endendticker = Ticker.new(MockPrice.new("MSFT"))DRb.start_service('druby://localhost:9001', ticker)puts 'Нажмите [return] для завершения.'getsНа платформе Windows примененный способ завершения программы вызывает сложности. Функция
getsgetsDRb.thread.joinНеудивительно, что клиент (листинг 20.3) начинает с установления соединения с сервером. Он получает ссылку на объект показа котировок и устанавливает верхний и нижний пороги изменения цены. Затем клиент выводит сообщение пользователю всякий раз, как цена выходит за пределы указанного диапазона.
require "drb"class Warner include DRbUndumped def initialize(ticker, limit) @limit = limit ticker.add_observer(self) # Любой объект Warner # является наблюдателем. endendclass WarnLow < Warner def update(time, price) # Обратный вызов наблюдателя.
