Ruby design patterns: Observer
Ruby design patterns: Observer
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.*
*- after wikipedia
Not as controversial as his fellow singelton, also observer pattern is a key part in MVC architecture.
Let’s get started:
require 'observer'
class Bodybuilder
include Observable
attr_reader :protein, :muscle
def initialize(protein, muscle)
@protein = protein
@muscle = muscle
add_observer(Log.new)
end
def power(exercise)
@muscle = exercise + protein
changed
notify_observers(self, muscle)
end
end
class Log
def update(bodybuilder, muscle)
open('./log.txt', 'a') do |f|
f << Time.now.strftime("%d/%m/%Y %H:%M") + " " +
"Bodybuilder with #{bodybuilder.protein} grams of protein, grows pure #{muscle} grams of muscle!. \n"
end
end
end
bodybuilder = Bodybuilder.new(100, 50)
bodybuilder.power(30)
bodybuilder.power(400)
Ok, so what does our bodybuilder do?
We have two separate classes Bodybuilder and Log.
Bodybuilder class is the observable one the subject, and Log class is an observer.
In Bodybuilder class we include the Observable to mark this class as the observable one.
In the initialize method we only add, well add_observer - pretty logical.
The power method is also very simple there we are only letting know the observer that they
must observe it with notify_observers.
Class Log is a basic logger it writes to file log.txt date and time of app execution and
additional text, but only when something in Bodybuilder is changed.
Let’s give it a go and fire it up in terminal. Next thing we need to do is to cat log.txt
file and see what is inside:
#sample output
20/01/2017 18:26 Bodybuilder with 100 grams of protein, grows pure 130 grams of muscle!.
20/01/2017 18:26 Bodybuilder with 100 grams of protein, grows pure 500 grams of muscle!.
Good, it worked. Things changed in our bodybuilder and Log class responded to them by
logging the data to separate file, that is log.txt. Pretty handy stuff!
Cheers