Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@otobrglez
Created August 23, 2011 12:26
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save otobrglez/1164983 to your computer and use it in GitHub Desktop.
Save otobrglez/1164983 to your computer and use it in GitHub Desktop.
Experimenting with observer pattern (publish/subscribe pattern) in Ruby
# Simple Car class. Nothing special here...
class Car
attr_accessor :brand
attr_accessor :model
attr_accessor :year
def initialize(brand, model, year=2011)
@brand, @model, @year = brand, model, year
end
def to_s; "#{@brand}/#{@model} - #{@year}"; end
end
require "rubygems"
# require "pp"
# require "ruby-debug"
require "./car"
require "./observable"
require "./observer"
# Simple list of cars that can trigger events
class CarsList < Observable
attr_accessor :cars
# Initialize cars list
def initialize()
@cars = []
end
# Add another car to the list and trigger car_added event
def add(car)
@cars << car
trigger :car_added, car
end
# Trigger car_sold event and remove car from list
def sell(index)
trigger :car_sold, @cars[index]
@cars.delete_at index
end
def each &blk
@cars.send :each, &blk
end
end
# Following observer is happy when u sell car
class AccountingObserver < Observer
def car_sold(sender, car)
puts "Yey. We sold another car! " + car.to_s
end
end
# This observer detects when the car is added to list
class CarServisObserver < Observer
def car_added(sender, car)
puts "CarServisObserver received car : " + car.to_s
end
end
### ### ### ### ### ### ### ### ### ### ### ### ###
# Using pattern
my_cars = CarsList.new
my_cars.add_observer AccountingObserver.new # Add accounting observer
my_cars.add_observer CarServisObserver.new # Add car servis observer
# Add some cars
my_cars.add Car.new "Audi", "Q3", 2010
my_cars.add Car.new "BMW", "X6"
my_cars.add Car.new "BMW", "Z4", 2010
my_cars.add Car.new "Audi", "R8 Coupe 5.2 FSI quattro"
# Sell 2nd car on list
my_cars.sell 1
# Sell another car
my_cars.sell 1
# Add another car to the list
my_cars.add Car.new "Audi", "R8 Coupe 5.2 FSI quattro"
# See all the cars out there
puts "\nList of my cars: "
my_cars.each do |car|
puts "# #{car}"
end
# This class is used when you want to observe object
class Observable
# Create emptry list of observers and add observer to it
def add_observer(observer)
if @observers.nil?
@observers = []
end
@observers << observer
end
# Returning list of observers
def observers; @observers; end
# Trigger event with "any name u want" and attach sender and sending object
def trigger(event, object=nil)
@observers.each do |observer|
observer.send event, self, object
end
end
end
# This class represents observer
class Observer
# Call method/event if exists
def method_missing(method, *args, &block)
if self.respond_to? method
self.send(method, *args, &block)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment