-
-
Save jwigal/1658031 to your computer and use it in GitHub Desktop.
Experimenting with observer pattern (publish/subscribe pattern) in Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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