Skip to content

Instantly share code, notes, and snippets.

@nicholasjhenry
Last active December 14, 2015 21:39
Show Gist options
  • Select an option

  • Save nicholasjhenry/5153165 to your computer and use it in GitHub Desktop.

Select an option

Save nicholasjhenry/5153165 to your computer and use it in GitHub Desktop.
Latest thoughts on service implementation
# Inspired by this thread:
# https://groups.google.com/forum/?fromgroups=#!msg/rubyparley/Rnm2tC0Ry8g/xoyIfH4Qb_AJ
#
# "My habit is to pass all the data for the operation in the constructor, and then have a generic `run` method to make it go.
# That way I can separate creation from execution should I want to, just as you can with a block." - Martin Fowler
class CheckoutController
def purchase
purchase_order
end
private
def purchase_order
PurchaseOrder.call(order)
end
def order
@order ||= Order.find_by_number(params[:id])
end
end
class PurchaseOrder
def self.call(order)
purchase_order = PurchaseOrder.new
redeem_store_credits = RedeemStoreCredits.new
prepare_payout = PreparePayout.new
purchase_order.addListener(redeem_store_credits)
purchase_order.addListener(prepare_payout)
purchase_order.call(order)
end
attr_reader :order
def add_listener(listener)
@listener ||= []
@listener << listener
end
def call
@order = order
# do stuff
notify_listeners
end
private
def notify_listeners
@listeners.each { |listener| listener.call(order) }
end
end
class RedeemStoreCredits
attr_reader :order, :store_credits
def initialize(store_credits=nil)
@store_credits = store_credits
end
def call(order)
# do stuff
end
private
def store_credits
@store_credits ||= StoreCredit.redeemable_for_user(order.user)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment