Skip to content

Instantly share code, notes, and snippets.

@joalbertg
Created September 21, 2020 02:17
Show Gist options
  • Save joalbertg/8fd55772d0bff1001f893c87214668ff to your computer and use it in GitHub Desktop.
Save joalbertg/8fd55772d0bff1001f893c87214668ff to your computer and use it in GitHub Desktop.
ruby: Observer Pattern

Observer Pattern

V1
  name:   Fred Flintstone
  title:  Crane Operator
  salary: 30000
35000

==========================================================================================
V2
Cut a new check for Fred!
His salary is now 35000!

==========================================================================================
V3
Cut a new check for Fred!
His salary is now 35000!
Cut a new check for Fred!
His salary is now 90000!
Send Fred a new tax bill!

==========================================================================================
V4
Cut a new check for Fred!
His salary is now 35000!

==========================================================================================
V5
Cut a new check for Fred!
His salary is now 35000!

==========================================================================================
V6
Cut a new check for Fred!
His salary is now 35000!

==========================================================================================
V7
Cut a new check for Fred!
His salary is now 35000!

==========================================================================================
module Observer
module V1
class Employee
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
@name = name
@title = title
@salary = salary
end
end
end
module V2
class Employee
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary, payroll)
@name = name
@title = title
@salary = salary
@payroll = payroll
end
def salary=(new_salary)
@salary = new_salary
payroll.update(self)
end
private
attr_reader :payroll
end
class Payroll
def update(changed_employee)
puts "Cut a new check for #{changed_employee.name}!"
puts "His salary is now #{changed_employee.salary}!"
end
end
end
module V3
class Employee
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
@name = name
@title = title
@salary = salary
@observers = []
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
def add_observer(observer)
observers << observer
end
def delete_observer(observer)
observer.delete(observer)
end
private
attr_reader :observers
def notify_observers
observers.each do |observer|
observer.update(self)
end
end
end
class TaxMan
def update(changed_employee)
puts "Send #{changed_employee.name} a new tax bill!"
end
end
end
module V4
class Subject
def initialize
@observers = []
end
def add_observer(observer)
observers << observer
end
def delete_observer(observer)
observers.delete(observer)
end
private
attr_reader :observers
def notify_observers
observers.each do |observer|
observer.update(self)
end
end
end
class Employee < Subject
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
super()
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
end
end
module V5
module Subject
def initialize
@observers = []
end
def add_observer(observer)
observers << observer
end
def delete_observer(observer)
observers.delete(observer)
end
private
attr_reader :observers
def notify_observers
observers.each do |observer|
observer.update(self)
end
end
end
class Employee
include Subject
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
super()
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
end
end
module V6
require 'observer'
class Employee
include Observable
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
changed
notify_observers(self)
end
end
end
module V7
module Subject
def initialize
@observers = []
end
def add_observer(&observer)
observers << observer
end
def delete_observer(observer)
observers.delete(observer)
end
private
attr_reader :observers
def notify_observers
observers.each do |observer|
observer.call(self)
end
end
end
class Employee
include Subject
attr_reader :name
attr_accessor :title, :salary
def initialize(name, title, salary)
super()
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
end
end
end
split = <<-EOF
==========================================================================================
EOF
puts 'V1'
fred = Observer::V1::Employee.new('Fred Flintstone', 'Crane Operator', 30_000)
puts <<-EOF
name: #{fred.name}
title: #{fred.title}
salary: #{fred.salary}
EOF
# Give Fred a raise
fred.salary = 35_000
puts fred.salary
puts split
puts 'V2'
payroll = Observer::V2::Payroll.new
fred = Observer::V2::Employee.new('Fred', 'Crane Operator', 30_000, payroll)
fred.salary = 35_000
puts split
puts 'V3'
fred = Observer::V3::Employee.new('Fred', 'Crane Operator', 30_000)
payroll = Observer::V2::Payroll.new
fred.add_observer(payroll)
fred.salary = 35_000
tax_man = Observer::V3::TaxMan.new
fred.add_observer(tax_man)
fred.salary = 90_000
puts split
puts 'V4'
fred = Observer::V4::Employee.new('Fred', 'Crane Operator', 30_000)
payroll = Observer::V2::Payroll.new
fred.add_observer(payroll)
fred.salary = 35_000
puts split
puts 'V5'
fred = Observer::V5::Employee.new('Fred', 'Crane Operator', 30_000)
payroll = Observer::V2::Payroll.new
fred.add_observer(payroll)
fred.salary = 35_000
puts split
puts 'V6'
fred = Observer::V6::Employee.new('Fred', 'Crane Operator', 30_000)
payroll = Observer::V2::Payroll.new
fred.add_observer(payroll)
fred.salary = 35_000
puts split
puts 'V7'
fred = Observer::V7::Employee.new('Fred', 'Crane Operator', 30_000)
fred.add_observer do |changed_employee|
puts "Cut a new check for #{changed_employee.name}!"
puts "His salary is now #{changed_employee.salary}!"
end
fred.salary = 35_000
puts split
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment