SlideShare a Scribd company logo
1 of 57
Download to read offline
DESIGN PATTERNS
THE WAY
Hello ConFoo!
I AM FRED HEATH
Developer, Problem
solver, Ruby evangelist,
Agile practitioner.
You can find me at:
@FredAtBootstrap
bootstrap.me.uk
Let’s start with the
first set of slides
The
gospel
according
to Russ
1
STRATEGY
APPLICATIONS
▪ Dynamically choose algorithm
Strategy
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
# 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
$> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }, WorldPayPayment.
new)
$> purchase.pay
.....paying $13.7 by WorldPay
$> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }, PayPalPayment.
new)
$> purchase.pay
.....paying $13.7 by PayPal
Lambda: an anonymous, first-class
function.
def m(&a_lambda)
a_lambda.call
end
$> m {puts "this is a lambda"}
"this is a lambda"
def m(&a_lambda)
x = 'hello'
a_lambda.call(x)
end
$> m {|x| puts "x is: #{x}"}
"x is: hello"
class PayPalPayment
def pay(sum)
puts ".....paying $#{sum} by
PayPal"
end
end
class WorldPayPayment
def pay(sum)
puts ".....paying $#{sum} by
WorldPay"
end
end
class BitcoinPayment
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
#class PayPalPayment
# def pay(sum)
# puts ".....paying $#{sum} by
PayPal"
# end
#end
#class WorldPayPayment
# def pay(sum)
# puts ".....paying $#{sum} by
WorldPay"
# end
#end
#class BitcoinPayment
# 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
#class PayPalPayment
# def pay(sum)
# puts ".....paying $#{sum} by
PayPal"
# end
#end
#class WorldPayPayment
# def pay(sum)
# puts ".....paying $#{sum} by
WorldPay"
# end
#end
#class BitcoinPayment
# 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.call(@sum)
end
end
$> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }) {|sum| puts ".....
paying $#{sum} by WorldPay"}
$> purchase.pay
.....paying $13.7 by WorldPay
$> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }) {|sum| puts ".....
paying $#{sum} by Amazon Payments"}
$> purchase.pay
.....paying $13.7 by Amazon Payments
From:
To:
2
COMMAND
APPLICATIONS
▪ User Interfaces
▪ Queuing/Logging (Wizards)
▪ Do-Undo-Redo
Command
class Command
def do_command
raise "can't do this here"
end
def undo_command
raise "can't do this here"
end
end
class Incrementer < Command
def initialize(aggregate)
@aggregate = aggregate
end
def do_command
@aggregate += 2
end
def undo_command
@aggregate -= 2
end
end
#class Command
# def do_command
# raise "can't do this here"
# end
# def undo_command
# raise "can't do this here"
# end
#end
class Incrementer #< Command
def initialize(aggregate)
@aggregate = aggregate
end
def do_command
@aggregate += 2
end
def undo_command
@aggregate -= 2
end
end
count = 0
commands = []
(1..10).each do |i|
commands << Incrementer.new(count)
end
puts "Count initially is: #{count}"
commands.each {|cmd| cmd.do_command}
puts "Count after doing commands: #{count}
Count initially is: 0
Count after doing commands: 0
Closure: A first-class function
that has lexical scope.
outer = 1
def m a_var
inner = 99
puts "inner var = #{inner}"
proc {inner + a_var}
end
p = m(outer)
puts "p is a #{p.class}"
puts "result of proc call: #{p.call}"
inner var = 99
p is a Proc
result of proc call: 100
outer = 1
def m a_var
inner = 99
puts "inner var = #{inner}"
proc {inner + a_var}
end
p = m(outer)
puts "p is a #{p.class}"
outer = 0
puts "changed outer to #{outer}"
puts "result of proc call: #{p.call}"
inner var = 99
p is a Proc
changed outer to 0
result of proc call: 100
class Command
attr_accessor :cmd, :uncmd
def initialize(do_command, undo_command)
@cmd = do_command
@uncmd = undo_command
end
def do_command
@cmd.call
end
def undo_command
@uncmd.call
end
end
count = 0
commands = []
(1..10).each do |i|
commands << Command.new(proc {count += 2}, proc {count -= 2})
end
puts "Count initially is: #{count}"
commands.each {|cmd| cmd.do_command}
puts "Count after doing commands: #{count}"
Count initially is: 0
Count after doing commands: 20
count = 0
commands = []
(1..10).each do |i|
commands << Command.new(proc {count += 2}, proc {count -= 2})
end
puts "Count initially is: #{count}"
commands.each {|cmd| cmd.do_command}
puts "Count after doing commands: #{count}"
commands.reverse_each {|cmd| cmd.undo_command}
puts "Count after un-doing commands: #{count}"
commands.each {|cmd| cmd.do_command}
puts "Count after re-doing commands: #{count}"
Count initially is: 0
Count after doing commands: 20
Count after un-doing commands: 0
Count after re-doing commands: 20
From:
To:
3
PROXY
APPLICATIONS
▪ Protection
▪ Remote Access
▪ Lazy Creation (Virtual Proxy)
Proxy
class Car
def drive
raise "use the Proxy instead"
end
end
class RealCar < Car
def drive
puts "vroom,vroom..."
end
end
class ProxyCar < Car
def initialize(real_car, driver_age)
@driver_age = driver_age
@real_car = real_car
end
def check_access
@driver_age > 16
end
def get_real_car
@real_car || (@real_car = Car.new
(@driver_age))
end
def drive
car = get_real_car
check_access ? car.drive : puts("Sorry,
you're too young to drive")
end
end
class RealCar
def drive
puts "vroom,vroom..."
end
end
class ProxyCar
def initialize(real_car, driver_age)
@driver_age = driver_age
@real_car = real_car
end
def check_access
@driver_age > 16
end
def get_real_car
@real_car || (@real_car = Car.new
(@driver_age))
end
def drive
car = get_real_car
check_access ? car.drive : puts("Sorry,
you're too young to drive")
end
end
class RealCar
def drive
puts "vroom,vroom..."
end
end
class Client
attr_reader :age
def initialize(age)
@age = age
end
def drive(car)
car.drive
end
end
class ProxyCar
def initialize(real_car, driver_age)
@driver_age = driver_age
@real_car = real_car
end
def check_access
@driver_age > 16
end
def get_real_car
@real_car || (@real_car = Car.new
(@driver_age))
end
def drive
car = get_real_car
check_access ? car.drive : puts("Sorry,
you're too young to drive")
end
end
tom = Client.new(25)
car = RealCar.new()
proxy = ProxyCar.new(car, tom.age)
tom.drive(proxy)
vroom,vroom...
tom = Client.new(15)
car = RealCar.new()
proxy = ProxyCar.new(car, tom.age)
tom.drive(proxy)
Sorry, you're too young to drive
Dynamic Dispatching: selecting
which method to call at run-time
puts [1, 2, 3].reverse
3
2
1
puts [1, 2, 3].send(:reverse)
3
2
1
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
a_method
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
a_method
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
a_method
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
a_method
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
a_method
BasicObject
Kernel
Object
MyClass
SuperClass
………..
………..
method_missing
BasicObject
method_missing()
Kernel
Object
MyClass
SuperClass
………..
………..
method_missing
raise “Undefined method”
class RealCar
def drive
puts "vroom,vroom..."
end
end
class Client
attr_reader :age
def initialize(age)
@age = age
end
def drive(car)
car.drive
end
end
class ProxyCar
def initialize(real_car, driver_age)
@driver_age = driver_age
@real_car = real_car
end
def method_missing(name, *args)
car = get_real_car
check_access ? car.send(name, *args) :
puts("Sorry, can't do this")
end
def check_access
@driver_age > 16
end
def get_real_car
@real_car || (@real_car = Car.new
(@driver_age))
end
end
tom = Client.new(25)
car = RealCar.new()
proxy = ProxyCar.new(car, tom.age)
tom.drive(proxy)
vroom,vroom...
Perfection [in design] is
achieved, not when there is
nothing more to add, but when
there is nothing left to take
away.
- Antoine de Saint-Exupéry
CREDITS
Special thanks to all the people who made and released
these awesome resources for free:
▪ Busy Icons by Olly Holovchenko
▪ Presentation template by SlidesCarnival
▪ Photographs by Unsplash
GitHub Gists
▪ https://gist.github.
com/2809a0410ec452b64f4d
▪ https://gist.github.
com/d3638a2d15879806e679
▪ https://gist.github.
com/c1d7de9da194922305b2
ANY QUESTIONS?
You can find me at:
FredAtBootstrap
fred@bootstrap.me.uk

More Related Content

What's hot

Rubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in RubyRubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in RubyRuby Bangladesh
 
Worth the hype - styled components
Worth the hype - styled componentsWorth the hype - styled components
Worth the hype - styled componentskathrinholzmann
 
Source Filters in Perl 2010
Source Filters in Perl 2010Source Filters in Perl 2010
Source Filters in Perl 2010hendrikvb
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsLeonardo Soto
 
Turn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesTurn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesjerryorr
 
Wake up Neo... Dependencies have you
Wake up Neo... Dependencies have youWake up Neo... Dependencies have you
Wake up Neo... Dependencies have youIvan Mosiev
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Samuel ROZE
 
Do more with less code in a serverless world
Do more with less code in a serverless worldDo more with less code in a serverless world
Do more with less code in a serverless worldjeromevdl
 
Saferpay Checkout Page - PHP Sample (Hosting)
Saferpay Checkout Page - PHP Sample (Hosting)Saferpay Checkout Page - PHP Sample (Hosting)
Saferpay Checkout Page - PHP Sample (Hosting)webhostingguy
 
Candies for everybody - Meet Magento Italia 2015
Candies for everybody - Meet Magento Italia 2015Candies for everybody - Meet Magento Italia 2015
Candies for everybody - Meet Magento Italia 2015Alberto López Martín
 
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.Meet Magento Italy
 
HTML5 workshop, forms
HTML5 workshop, formsHTML5 workshop, forms
HTML5 workshop, formsRobert Nyman
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Building Data Rich Interfaces with JavaFX
Building Data Rich Interfaces with JavaFXBuilding Data Rich Interfaces with JavaFX
Building Data Rich Interfaces with JavaFXStephen Chin
 

What's hot (20)

Rubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in RubyRubyconf Bangladesh 2017 - Lets start coding in Ruby
Rubyconf Bangladesh 2017 - Lets start coding in Ruby
 
PHP Basics
PHP BasicsPHP Basics
PHP Basics
 
Worth the hype - styled components
Worth the hype - styled componentsWorth the hype - styled components
Worth the hype - styled components
 
Source Filters in Perl 2010
Source Filters in Perl 2010Source Filters in Perl 2010
Source Filters in Perl 2010
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivars
 
Turn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesTurn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modules
 
Wake up Neo... Dependencies have you
Wake up Neo... Dependencies have youWake up Neo... Dependencies have you
Wake up Neo... Dependencies have you
 
Php introduction
Php introductionPhp introduction
Php introduction
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)
 
Do more with less code in a serverless world
Do more with less code in a serverless worldDo more with less code in a serverless world
Do more with less code in a serverless world
 
Saferpay Checkout Page - PHP Sample (Hosting)
Saferpay Checkout Page - PHP Sample (Hosting)Saferpay Checkout Page - PHP Sample (Hosting)
Saferpay Checkout Page - PHP Sample (Hosting)
 
Paypal + symfony
Paypal + symfonyPaypal + symfony
Paypal + symfony
 
Candies for everybody - Meet Magento Italia 2015
Candies for everybody - Meet Magento Italia 2015Candies for everybody - Meet Magento Italia 2015
Candies for everybody - Meet Magento Italia 2015
 
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.
Alberto López: Candies for everybody: hacking from 9 a.m. to 6 p.m.
 
HTML5 workshop, forms
HTML5 workshop, formsHTML5 workshop, forms
HTML5 workshop, forms
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Data Types In PHP
Data Types In PHPData Types In PHP
Data Types In PHP
 
Building Data Rich Interfaces with JavaFX
Building Data Rich Interfaces with JavaFXBuilding Data Rich Interfaces with JavaFX
Building Data Rich Interfaces with JavaFX
 
Codeware
CodewareCodeware
Codeware
 
The new form framework
The new form frameworkThe new form framework
The new form framework
 

Similar to Design Patterns the Ruby way - ConFoo 2015

Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Symfony2 - extending the console component
Symfony2 - extending the console componentSymfony2 - extending the console component
Symfony2 - extending the console componentHugo Hamon
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015Fernando Hamasaki de Amorim
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Toolschrismdp
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...Mateusz Zalewski
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with WebratLuismi Cavallé
 

Similar to Design Patterns the Ruby way - ConFoo 2015 (20)

Intro to ruby
Intro to rubyIntro to ruby
Intro to ruby
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Symfony2 - extending the console component
Symfony2 - extending the console componentSymfony2 - extending the console component
Symfony2 - extending the console component
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
Ruby
RubyRuby
Ruby
 
Beware sharp tools
Beware sharp toolsBeware sharp tools
Beware sharp tools
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
ES6, WTF?
ES6, WTF?ES6, WTF?
ES6, WTF?
 
Beware: Sharp Tools
Beware: Sharp ToolsBeware: Sharp Tools
Beware: Sharp Tools
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Php functions
Php functionsPhp functions
Php functions
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with Webrat
 
Why ruby
Why rubyWhy ruby
Why ruby
 

More from Fred Heath

Agile software requirements management with Impact Mapping and BDD
Agile software requirements management with Impact Mapping and BDDAgile software requirements management with Impact Mapping and BDD
Agile software requirements management with Impact Mapping and BDDFred Heath
 
Nim programming language - DevFest Berlin 2019
Nim programming language -  DevFest Berlin 2019Nim programming language -  DevFest Berlin 2019
Nim programming language - DevFest Berlin 2019Fred Heath
 
USP Estimation - SwanseaCon 2016
USP Estimation - SwanseaCon 2016USP Estimation - SwanseaCon 2016
USP Estimation - SwanseaCon 2016Fred Heath
 
Introduction to Nim
Introduction to NimIntroduction to Nim
Introduction to NimFred Heath
 
Port80: the uncertainty principle
Port80: the uncertainty principlePort80: the uncertainty principle
Port80: the uncertainty principleFred Heath
 
Agile diff usp
Agile diff uspAgile diff usp
Agile diff uspFred Heath
 
User Story Point estimation method at ConFoo 2015
User Story Point estimation method at ConFoo 2015User Story Point estimation method at ConFoo 2015
User Story Point estimation method at ConFoo 2015Fred Heath
 

More from Fred Heath (7)

Agile software requirements management with Impact Mapping and BDD
Agile software requirements management with Impact Mapping and BDDAgile software requirements management with Impact Mapping and BDD
Agile software requirements management with Impact Mapping and BDD
 
Nim programming language - DevFest Berlin 2019
Nim programming language -  DevFest Berlin 2019Nim programming language -  DevFest Berlin 2019
Nim programming language - DevFest Berlin 2019
 
USP Estimation - SwanseaCon 2016
USP Estimation - SwanseaCon 2016USP Estimation - SwanseaCon 2016
USP Estimation - SwanseaCon 2016
 
Introduction to Nim
Introduction to NimIntroduction to Nim
Introduction to Nim
 
Port80: the uncertainty principle
Port80: the uncertainty principlePort80: the uncertainty principle
Port80: the uncertainty principle
 
Agile diff usp
Agile diff uspAgile diff usp
Agile diff usp
 
User Story Point estimation method at ConFoo 2015
User Story Point estimation method at ConFoo 2015User Story Point estimation method at ConFoo 2015
User Story Point estimation method at ConFoo 2015
 

Recently uploaded

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 

Recently uploaded (20)

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 

Design Patterns the Ruby way - ConFoo 2015

  • 2. Hello ConFoo! I AM FRED HEATH Developer, Problem solver, Ruby evangelist, Agile practitioner. You can find me at: @FredAtBootstrap bootstrap.me.uk
  • 3. Let’s start with the first set of slides
  • 8. 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
  • 9. # 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
  • 10. $> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }, WorldPayPayment. new) $> purchase.pay .....paying $13.7 by WorldPay $> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }, PayPalPayment. new) $> purchase.pay .....paying $13.7 by PayPal
  • 11. Lambda: an anonymous, first-class function.
  • 12. def m(&a_lambda) a_lambda.call end $> m {puts "this is a lambda"} "this is a lambda"
  • 13. def m(&a_lambda) x = 'hello' a_lambda.call(x) end $> m {|x| puts "x is: #{x}"} "x is: hello"
  • 14. class PayPalPayment def pay(sum) puts ".....paying $#{sum} by PayPal" end end class WorldPayPayment def pay(sum) puts ".....paying $#{sum} by WorldPay" end end class BitcoinPayment 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
  • 15. #class PayPalPayment # def pay(sum) # puts ".....paying $#{sum} by PayPal" # end #end #class WorldPayPayment # def pay(sum) # puts ".....paying $#{sum} by WorldPay" # end #end #class BitcoinPayment # 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
  • 16. #class PayPalPayment # def pay(sum) # puts ".....paying $#{sum} by PayPal" # end #end #class WorldPayPayment # def pay(sum) # puts ".....paying $#{sum} by WorldPay" # end #end #class BitcoinPayment # 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.call(@sum) end end
  • 17. $> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }) {|sum| puts "..... paying $#{sum} by WorldPay"} $> purchase.pay .....paying $13.7 by WorldPay $> purchase = Purchase.new({cd_Wild_Beasts: 5.2, baseball_cap: 8.5 }) {|sum| puts "..... paying $#{sum} by Amazon Payments"} $> purchase.pay .....paying $13.7 by Amazon Payments
  • 18. From:
  • 19. To:
  • 21. APPLICATIONS ▪ User Interfaces ▪ Queuing/Logging (Wizards) ▪ Do-Undo-Redo
  • 23. class Command def do_command raise "can't do this here" end def undo_command raise "can't do this here" end end class Incrementer < Command def initialize(aggregate) @aggregate = aggregate end def do_command @aggregate += 2 end def undo_command @aggregate -= 2 end end
  • 24. #class Command # def do_command # raise "can't do this here" # end # def undo_command # raise "can't do this here" # end #end class Incrementer #< Command def initialize(aggregate) @aggregate = aggregate end def do_command @aggregate += 2 end def undo_command @aggregate -= 2 end end
  • 25. count = 0 commands = [] (1..10).each do |i| commands << Incrementer.new(count) end puts "Count initially is: #{count}" commands.each {|cmd| cmd.do_command} puts "Count after doing commands: #{count} Count initially is: 0 Count after doing commands: 0
  • 26. Closure: A first-class function that has lexical scope.
  • 27. outer = 1 def m a_var inner = 99 puts "inner var = #{inner}" proc {inner + a_var} end p = m(outer) puts "p is a #{p.class}" puts "result of proc call: #{p.call}" inner var = 99 p is a Proc result of proc call: 100
  • 28. outer = 1 def m a_var inner = 99 puts "inner var = #{inner}" proc {inner + a_var} end p = m(outer) puts "p is a #{p.class}" outer = 0 puts "changed outer to #{outer}" puts "result of proc call: #{p.call}" inner var = 99 p is a Proc changed outer to 0 result of proc call: 100
  • 29. class Command attr_accessor :cmd, :uncmd def initialize(do_command, undo_command) @cmd = do_command @uncmd = undo_command end def do_command @cmd.call end def undo_command @uncmd.call end end
  • 30. count = 0 commands = [] (1..10).each do |i| commands << Command.new(proc {count += 2}, proc {count -= 2}) end puts "Count initially is: #{count}" commands.each {|cmd| cmd.do_command} puts "Count after doing commands: #{count}" Count initially is: 0 Count after doing commands: 20
  • 31. count = 0 commands = [] (1..10).each do |i| commands << Command.new(proc {count += 2}, proc {count -= 2}) end puts "Count initially is: #{count}" commands.each {|cmd| cmd.do_command} puts "Count after doing commands: #{count}" commands.reverse_each {|cmd| cmd.undo_command} puts "Count after un-doing commands: #{count}" commands.each {|cmd| cmd.do_command} puts "Count after re-doing commands: #{count}" Count initially is: 0 Count after doing commands: 20 Count after un-doing commands: 0 Count after re-doing commands: 20
  • 32. From:
  • 33. To:
  • 35. APPLICATIONS ▪ Protection ▪ Remote Access ▪ Lazy Creation (Virtual Proxy)
  • 36. Proxy
  • 37. class Car def drive raise "use the Proxy instead" end end class RealCar < Car def drive puts "vroom,vroom..." end end class ProxyCar < Car def initialize(real_car, driver_age) @driver_age = driver_age @real_car = real_car end def check_access @driver_age > 16 end def get_real_car @real_car || (@real_car = Car.new (@driver_age)) end def drive car = get_real_car check_access ? car.drive : puts("Sorry, you're too young to drive") end end
  • 38. class RealCar def drive puts "vroom,vroom..." end end class ProxyCar def initialize(real_car, driver_age) @driver_age = driver_age @real_car = real_car end def check_access @driver_age > 16 end def get_real_car @real_car || (@real_car = Car.new (@driver_age)) end def drive car = get_real_car check_access ? car.drive : puts("Sorry, you're too young to drive") end end
  • 39. class RealCar def drive puts "vroom,vroom..." end end class Client attr_reader :age def initialize(age) @age = age end def drive(car) car.drive end end class ProxyCar def initialize(real_car, driver_age) @driver_age = driver_age @real_car = real_car end def check_access @driver_age > 16 end def get_real_car @real_car || (@real_car = Car.new (@driver_age)) end def drive car = get_real_car check_access ? car.drive : puts("Sorry, you're too young to drive") end end
  • 40. tom = Client.new(25) car = RealCar.new() proxy = ProxyCar.new(car, tom.age) tom.drive(proxy) vroom,vroom...
  • 41. tom = Client.new(15) car = RealCar.new() proxy = ProxyCar.new(car, tom.age) tom.drive(proxy) Sorry, you're too young to drive
  • 42. Dynamic Dispatching: selecting which method to call at run-time
  • 43. puts [1, 2, 3].reverse 3 2 1
  • 44. puts [1, 2, 3].send(:reverse) 3 2 1
  • 52. class RealCar def drive puts "vroom,vroom..." end end class Client attr_reader :age def initialize(age) @age = age end def drive(car) car.drive end end class ProxyCar def initialize(real_car, driver_age) @driver_age = driver_age @real_car = real_car end def method_missing(name, *args) car = get_real_car check_access ? car.send(name, *args) : puts("Sorry, can't do this") end def check_access @driver_age > 16 end def get_real_car @real_car || (@real_car = Car.new (@driver_age)) end end
  • 53. tom = Client.new(25) car = RealCar.new() proxy = ProxyCar.new(car, tom.age) tom.drive(proxy) vroom,vroom...
  • 54. Perfection [in design] is achieved, not when there is nothing more to add, but when there is nothing left to take away. - Antoine de Saint-Exupéry
  • 55. CREDITS Special thanks to all the people who made and released these awesome resources for free: ▪ Busy Icons by Olly Holovchenko ▪ Presentation template by SlidesCarnival ▪ Photographs by Unsplash
  • 56. GitHub Gists ▪ https://gist.github. com/2809a0410ec452b64f4d ▪ https://gist.github. com/d3638a2d15879806e679 ▪ https://gist.github. com/c1d7de9da194922305b2
  • 57. ANY QUESTIONS? You can find me at: FredAtBootstrap fred@bootstrap.me.uk