Software design patterns help to speed up the development process. These have been proven and tested in this field while resolving specific problems in the best possible way. These patterns are abstract solutions that can be mapped in myriad situations and are classified in the following categories:
- Behavioral patterns
- Structural patterns
- Creational patterns
- Concurrency patterns
.
Observer pattern falls in behavioral patterns category. As the pattern name “Observer” suggests that part of code will observe something such as temperature, stock value or a new user registration, etc. The subject of the observation is an entity that runs the process to be observed (such as user registration). Whenever something of interest happens, the subject notifies the Observer about the event. The Observer then process the information and take some action.
This post explains how to implement an observer pattern in Ruby. Additionally, it contains ActiveRecord and Mongoid based implementations to give an idea of its working in Ruby on Rails.
Implementation in Ruby
The class name of the ‘observer’ object is generally created by appending the word ‘Observer’ to the class name of the subject for example, UserObserver or StockObserver. Below is an example in which the file that contains code for StockObserver is named as stock_observer.rb.
Adding One Observer
Add the following code in stock.rb file:
#!/usr/bin/ruby
load 'stock_observer.rb'
class Stock
attr_reader :minimum_quantity_limit, :observer
attr_accessor :available_quantity#, :observer
def initialize(available_quantity, minimum_quantity_limit)
@available_quantity = available_quantity
@minimum_quantity_limit = minimum_quantity_limit
@observer = StockObserver.new
end
def update_available_quantity(available_quantity)
@available_quantity = available_quantity
notify_observer
end
private
def notify_observer
@observer.notify(self)
end
s = Stock.new 40,10
puts s.inspect
s.update_available_quantity(20)
s.update_available_quantity(15)
s.update_available_quantity(10)
s.update_available_quantity(9)
s.update_available_quantity(5)
end
Now add the following code in stock_observer.rb file:
class StockObserver
def notify(stock)
if stock.available_quantity <= stock.minimum_quantity_limit
puts "Stock reached minimal limit! Minimum Quantity Limit: #{stock.minimum_quantity_limit} Available Quantity: #{stock.available_quantity}"
#Code to send email to purchase dept
else
puts "Available Quantity: #{stock.available_quantity}"
end
end
end
The output for stock.rb command will be:
Available Quantity: 20
Available Quantity: 15
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 10
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 9
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 5
In stock.rb file, only one observer has been added.
Adding Multiple Observers
For adding multiple observers in stock.rb file, use the following code:
#!/usr/bin/ruby
load 'stock_observer.rb'
load 'test_observer.rb'
class Stock
attr_reader :minimum_quantity_limit, :observers
attr_accessor :available_quantity
def initialize(available_quantity, minimum_quantity_limit)
@available_quantity = available_quantity
@minimum_quantity_limit = minimum_quantity_limit
@observers = []
end
def update_available_quantity(available_quantity)
@available_quantity = available_quantity
notify_observers
end
def add_observers(*observer_instances)
observer_instances.each{|observer_instance| observers << observer_instance}
end
private
def notify_observers
observers.each{|observer| observer.notify(self) }
end
s=Stock.new 40,10
s.add_observers(StockObserver.new, TestObserver.new)
puts s.inspect
s.update_available_quantity(20)
s.update_available_quantity(15)
s.update_available_quantity(10)
s.update_available_quantity(9)
s.update_available_quantity(5)
end
The output will be:
Available Quantity: 20
In Test Observer
Available Quantity: 15
In Test Observer
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 10
In Test Observer
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 9
In Test Observer
Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 5
In Test Observer
This is how custom observers has been created.
Creating Observers in Rails using ActiveRecord and Mongoid
Ruby on Rails also provides a way to create observers that requires much less code. For writing observers in Ruby on Rails using ActiveRecord, add the following code:
class StockObserver < ActiveRecord::Observer
def after_update(stock)
if stock.quantity <= stock.minial_limit
#send email code here
end
end
end
In Mongoid, just replace ActiveRecord::Observer with Mongoid::Observer. Rest code will remain the same.
Activation of Observers
In config/application.rb file, you need to register observers. Only registered observers are activated. This can be done by adding the following line of code to the body of class Application < Rails::Application in file application.rb in case of ActiveRecord:
config.active_record.observers = :stock_observer, :registration_observer
In case of Mongoid, add the following:
config.mongoid.observers = :stock_observer, :registration_observer
0 Comments