Model app behavior from the old way to the new way, with bounded contexts:
Old way:
class TripsController < ApplicationController
module Ridesharing | |
class RidesController < ApplicationController | |
def post | |
# Hail a time-traveling Delorean: | |
HailDelorean.hail(current_user.id) | |
render text: 'Hailing a cab, please wait for a response...' | |
end | |
end | |
end | |
module Ridesharing | |
class HailDelorean | |
include Wisper::Broadcaster | |
def self.hail(passenger_id) | |
broadcast(:hail, passenger_id) | |
end | |
end | |
end | |
module DriverRouting | |
# Note that this class is both a subscriber and a publisher | |
class FindDriver | |
include Wisper::Publisher | |
def self.hail(passenger_id) | |
# Do slow, complex hairy routefinding/optimization/messaging behind the scenes: | |
driver = find_driver_for(passenger_id) | |
if driver | |
broadcast('driver_found', passenger_id, driver.id) | |
else | |
broadcast('driver_not_found', passenger_id) | |
end | |
end | |
end | |
end | |
# Finally, we add handlers (subscribers) to these domain objects: | |
module Ridesharing | |
class NotifyPassengerWithDriverStatus | |
def self.driver_found | |
# send them a text message :) | |
end | |
def self.driver_not_found | |
# send them a text message :( | |
end | |
end | |
end | |
# Now let's link it together with subscriptions: | |
# config/initializers/domain_event_subscriptions.rb | |
Ridesharing::HailDelorean.subscribe(DriverRouting::FindDriver, async: true) | |
DriverRouting::FindDriver.subscribe(Ridesharing::NotifyPassengerWithDriverStatus, async: true) | |
Wisper.subscribe(AnalyticsListener, scope: "Ridesharing::NotifyPassengerWithDriverStatus", "DriverRouting::FindDriver"], async: true) |
module Ridesharing | |
class HailDelorean | |
include Wisper::Publisher | |
def hail!(user) | |
# broadcast() is a Wisper method to fire an event | |
driver = find_driver(user) | |
if driver | |
broadcast('hailed', driver) | |
else | |
broadcast('could_not_hail') | |
end | |
def find_driver(user) | |
# Here lies slow, complex domain logic | |
DriverRouting::FindDriver.new(user) | |
end | |
end | |
end |
Model app behavior from the old way to the new way, with bounded contexts:
Old way:
class TripsController < ApplicationController
module Ridesharing | |
class RidesController < ApplicationController | |
def post | |
# Hail a time-traveling Delorean: | |
command = HailDelorean.new | |
command.on('hailed') { |driver| | |
render text: "Hailed you a cab: #{driver} is arriving!" | |
} | |
.on('could_not_hail') { | |
render text: "Sorry, no dice." | |
} | |
command.hail!(current_user) | |
end | |
end | |
end |
module Ridesharing | |
class RidesController < ApplicationController | |
def post | |
# snip | |
command = HailDelorean.new(current_user) | |
# register the subscriber to the triggering action | |
command.subscribe(TrackSegmentAnalytics) | |
# snip | |
end | |
end | |
end |
class TrackSegmentAnalytics | |
def self.hailed(driver) | |
# fire analytics event to Segment | |
end | |
def self.could_not_hail | |
# fire analytics event to Segment | |
end | |
end |
# config/initializers/domain_event_subscriptions.rb | |
Wisper.subscribe(TrackSegmentAnalytics, scope: "HailDelorean") | |
# alternate form: | |
HailDelorean.subscribe(TrackSegmentAnalytics) |