Skip to content

Instantly share code, notes, and snippets.

@pashagray
Created July 16, 2020 06:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pashagray/6efab0b2048badb9166fc068046505d2 to your computer and use it in GitHub Desktop.
Save pashagray/6efab0b2048badb9166fc068046505d2 to your computer and use it in GitHub Desktop.
Simple example of pubsub pattern
module Publisher
def subscribe(subscribers)
@subscribers ||= [] # if @subscribers is nil, we initialize it as empty array, else we do nothing
@subscribers += subscribers
end
def broadcast(event, *payload)
@subscribers ||= [] # @subscribers is nil, we can't do each on it
@subscribers.each do |subscriber|
# If event is :item_added occured with payload item itself
# we send method :item_added to subscriber and bypass payload as argument if subscriber
# responds to it.
subscriber.public_send(event.to_sym, *payload) if subscriber.respond_to?(event)
end
end
end
class Item
attr_reader :code, :title
def initialize(code:, title:)
@code = code
@title = title
end
def to_s
"#{@code} #{@title}"
end
end
class Checkout
include Publisher
attr_reader :items
def initialize(subscribers:)
@items = []
subscribe(subscribers)
end
def add(item)
@items << item
broadcast(:item_added, item)
end
end
class Printer
def item_added(item)
print(item)
end
private
def print(message)
puts "[#{Time.now}] #{message}"
end
end
class SoundManager
def item_added(_)
beep!
end
def beep!
print "\a"
end
end
item1 = Item.new(code: "DRP", title: "Dr.Pepper")
item2 = Item.new(code: "CCL", title: "Coca-Cola")
checkout = Checkout.new(subscribers: [Printer.new, SoundManager.new])
checkout.add(item1)
checkout.add(item2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment