Created
February 11, 2015 20:39
-
-
Save RedFred7/2809a0410ec452b64f4d to your computer and use it in GitHub Desktop.
Design Patterns the Ruby way: strategy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####### STRATEGY PATTERN ############# | |
### way #1 | |
## The following code implements the strategy pattern in the traditional | |
## manner, i.e. with a separate class for each strategy (xxxPayment), | |
## which is then passed in the constructor of the Context class (in | |
## this case the Purchase class). The Context then selects a strategy | |
## at construction time and delegates its stragegy method (i.e. pay) to | |
## the strategy object | |
# this abstract base class is un-necessary in Ruby | |
# class PaymentStrategy | |
# def pay(sum) | |
# raise "can't call that!" | |
# end | |
# end | |
class PayPalPayment #< PaymentStrategy | |
def pay(sum) | |
puts ".....paying $#{sum} by PayPal" | |
end | |
end | |
class WorldPayPayment #< PaymentStrategy | |
def pay(sum) | |
puts ".....paying $#{sum} by WorldPay" | |
end | |
end | |
class BitcoinPayment #< PaymentStrategy | |
def pay(sum) | |
puts ".....paying $#{sum} by Bitcoin" | |
end | |
end | |
class Purchase | |
attr_reader :items, :sum | |
attr_accessor :payment_method | |
def initialize(items, payment_method) | |
@payment_method = payment_method | |
@sum = 0 | |
items.each do |item, value| | |
@sum += value | |
end | |
end | |
def pay | |
payment_method.pay(@sum) | |
end | |
end | |
puts "####### way 1" | |
purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }, WorldPayPayment.new) | |
purchase.pay | |
### way #2 | |
## This is the re-work of the pattern using code blocks (a.k.a lambdas) | |
## to dynamically define our strategy. We have no more need of Strategy | |
## objects, as we create our strategy dynamically in a code block, when | |
## we create the Purchase object. This is a much more flexible and scalable | |
## way of implementing the Strategy pattern. | |
class Purchase | |
attr_reader :items, :sum | |
attr_accessor :payment_method | |
def initialize(items, &payment_method) | |
@payment_method = payment_method | |
@sum = 0 | |
items.each do |item, value| | |
@sum += value | |
end | |
end | |
def pay | |
payment_method.call(@sum) | |
end | |
end | |
puts "####### way 2" | |
purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }) {|sum| puts ".....paying $#{sum} by WorldPay"} | |
purchase.pay |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment