Skip to content

Instantly share code, notes, and snippets.

@prognostikos
Last active December 25, 2015 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save prognostikos/6946226 to your computer and use it in GitHub Desktop.
Save prognostikos/6946226 to your computer and use it in GitHub Desktop.

Pub-Sub patterns for better OO code

  • it's not new; it's just event-driven programming
  • GoF observer pattern

I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning -- it took a while to see how to do messaging in a programming language efficiently enough to be useful) - Allen Kay

Recent articles/videos

Implementations

within one app

between services

EventBus.
subscribe(DonationReceipt.new).
subscribe(NotifyAccountingSystem.new).
subscribe(UpdatePublicStats.new).
subscribe(LogInternalMetrics.new).
subscribe(UpdateAnalyticsDashboard.new).
subscribe(RealtimeViewerUpdate.new)
class DonationsController # < ActionController::Base
def create
EventBus.subscribe(:donation_created) do |payload|
send_user_to_payment_gateway(payload[:donation])
end
EventBus.subscribe(:donation_invalid) do |payload|
render payload[:donation].errors, status: :bad_request
end
GiveDonation.new(current_user, params[:donation]).()
end
private
def send_user_to_payment_gateway
#...
end
end
class GiveDonation
attr_reader :donor,
:donation,
:event_bus
def initialize(donor, donation_attributes, options={})
@donor = donor
donation_class = options.fetch(:donation_class) { Donation }
@donation = donation_class.new(donation_attributes.merge(donor: donor))
@event_bus = options.fetch(:event_bus) { EventBus }
end
def call
if donation.valid?
donation.save!
event_bus.broadcast(:donation_created, donation: donation)
else
event_bus.broadcast(:donation_invalid, donation: donation)
end
end
end
class DonationReceipt
def donation_created(payload)
Mailer.delay.send_donation_receipt(payload[:donation])
end
end
class NotifyAccountingSystem
def donation_created(payload)
#..
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment