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) |