SlideShare una empresa de Scribd logo
1 de 26
Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/
Patrones de diseño
(en ruby)
Ignacio (Nacho) Facello
@nachof
nacho@nucleartesuji.com
Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/
Patrones de diseño
(en ruby)
Ignacio (Nacho) Facello
@nachof
nacho@nucleartesuji.com
Qué son patrones de diseño?
● Un patrón de diseño es una solución general
reutilizable a un problema de común ocurrencia
en el diseño de software (Wikipedia)
● Concepto originalmente usado en arquitectura
(Christopher Alexander)
● Popularizado en el libro Design Patterns:
Elements of Reusable Object-Oriented
Software, popularmente conocido como GoF
(Gang of Four), de Erich Gamma, Richard
Helm, Ralph Johnson, y John Vlissides.
Para qué sirven?
● Conocer una solución para un problema dado
es útil cuando uno se enfrenta a ese problema.
● Nos dan un lenguaje común.
● Suelen resultar en un buen diseño
Todo lo que sé de
patrones lo aprendí
jugando go
Joseki
El mismo joseki...
… en diferentes contextos.
Cuando no sirven...
● Que algo sea un patrón no quiere decir que sea
adecuado.
● El contexto lo es todo.
Lo importante: elegir la herramienta
adecuada
Photo by jannem http://www.flickr.com/photos/jannem/3312116875/
Algunos ejemplos de
patrones en Ruby
Singleton
require 'singleton' # From stdlib
class SingletonExample
include Singleton
end
one = SingletonExample.instance
two = SingletonExample.instance
puts one == two #=> true
Observer
require 'observer' # From stdlib
class Car
include Observable
def initialize
@fuel = 100
@speed = 0
end
def run
while @fuel > 0 do
@speed += 1
@fuel -= 1
changed
notify_observers (@speed,
@fuel)
end
end
end
class SpeedWarner
def initialize(car,
speed_limit)
@limit = speed_limit
car.add_observer(self)
end
def update(speed, fuel)
puts "Too fast!" if speed >
@limit
end
end
car = Car.new
SpeedWarner.new(car, 70)
FuelWarner.new(car, 10)
car.run
State
require 'state_pattern' # Gem by
@dcadenas
# http://github.com/dcadenas/state_pattern
class Stop < StatePattern::State
def next
sleep 3
transition_to (Go)
end
def color
"Red"
end
end
class Go < StatePattern::State
def next
sleep 2
transition_to (Caution)
end
def color
"Green"
end
end
class Caution < StatePattern::State
def next
sleep 1
transition_to (Stop)
end
def color
"Amber"
end
end
class TrafficSemaphore
include StatePattern
set_initial_state Stop
end
semaphore = TrafficSemaphore.new
loop do
puts semaphore.color
semaphore.next
end
Adapter
require 'forwardable'
class LegacyClassA
def some_method(a, b)
puts "#{a}, #{b} (old A)"
end
end
class LegacyClassB
def do_something(b, a)
puts "#{a}, #{b} (old B)"
end
end
class AdapterA
extend Forwardable
def initialize(adaptee)
@adaptee = adaptee
end
def_delegator :@adaptee,
:some_method, :action
end
class AdapterB
def initialize(adaptee)
@adaptee = adaptee
end
def action(a, b)
@adaptee.do_something(b, a)
end
end
adapted_a =
AdapterA.new(LegacyClassA.new)
adapted_b =
AdapterB.new(LegacyClassB.new)
[adapted_a, adapted_b].each { |
adapted| adapted.action("Hello",
"World") }
Iterator
class ArrayIterator
def initialize(array)
@array = array
@index = 0
end
def first
@index = 0
end
def next
@index += 1
end
def current
@array [@index]
end
def over?
@index >= @array.size
end
end
list = [1,2,3,4]
iterator = ArrayIterator.new(list)
while (!iterator.over?) do
puts iterator.current
iterator.next
end
Iterator
class ArrayIterator
def initialize(array)
@array = array
@index = 0
end
def first
@index = 0
end
def next
@index += 1
end
def current
@array [@index]
end
def over?
@index >= @array.size
end
end
list = [1,2,3,4]
iterator = ArrayIterator.new(list)
while (!iterator.over?) do
puts iterator.current
iterator.next
end
Mucho más sencillo...
list = [1,2,3,4]
list.each do |item|
puts item
end
Otras formas de iterar
list = [1,2,3,4]
list.each do |item|
puts item
end
list.map { |item| item * 2 } #=> [3,4,5,6]
list.any? { |item| item == 2 } #=> true
list.select { |item| item > 2 } #=> [3,4]
list.detect { |item| item > 2 } #=> 3
Strategy
require 'forwardable'
class Caveman
extend Forwardable
attr_accessor :strategy
def initialize(strategy =
DefaultStrategy.new)
@strategy = strategy
end
def_delegator :@strategy, :survive
def normal_day
wake_up
survive
go_to_sleep
end
def wake_up
puts "Waking up"
end
def go_to_sleep
puts "Sleep now"
end
end
class DefaultStrategy
def survive
puts "Hide from tigers"
end
end
class AggressiveStrategy
def survive
puts "Grab spear, hunt tigers"
end
end
class ConfusedStrategy
def survive
puts "Grab tiger, hunt spears"
end
end
og = Caveman.new
og.normal_day
og.strategy = AggressiveStrategy.new
og.normal_day
Strategy (con lambdas)
class Caveman
attr_accessor :strategy
def initialize(strategy = lambda { puts "Hide from tiger" })
@strategy = strategy
end
def normal_day
wake_up
survive
go_to_sleep
end
def survive
@strategy.call
end
def wake_up
puts "Waking up"
end
def go_to_sleep
puts "Sleep now"
end
end
og = Caveman.new
og.normal_day
og.strategy = lambda { puts "Grab spear, hunt tiger" }
og.normal_day
Algunos usos
● Rails: Model-View-Controller
● ActiveRecord::Observer: Observer
● Array#sort: Strategy
Algunos comentarios finales
● Stdlib y gemas son útiles
● Memorizarse los patrones y usarlos a cada
oportunidad no ayuda.
● Entender sus consecuencias, y su porqué, sí
sirve.
● “There may be a dozen different ways to
implement a [given pattern] - it doesn't have to
be done exactly like the GoF book or some web
page.” Paul Wheaton
(http://www.javaranch.com/patterns/)
Gracias :-)

Más contenido relacionado

Similar a Patrones de diseño (en Ruby) — RubyConf Uruguay 2010

From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scalatod esking
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyTypesafe
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonPython Ireland
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Databricks
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable LispAstrails
 
Design Patterns By Sisimon Soman
Design Patterns By Sisimon SomanDesign Patterns By Sisimon Soman
Design Patterns By Sisimon SomanSisimon Soman
 
Origins of Elixir programming language
Origins of Elixir programming languageOrigins of Elixir programming language
Origins of Elixir programming languagePivorak MeetUp
 
Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Jean Carlo Machado
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programaciónSoftware Guru
 
Yin Yangs of Software Development
Yin Yangs of Software DevelopmentYin Yangs of Software Development
Yin Yangs of Software DevelopmentNaveenkumar Muguda
 
Everything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-insEverything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-insAndrew Dupont
 
Design patterns - Using Ruby
Design patterns - Using RubyDesign patterns - Using Ruby
Design patterns - Using RubyShifa Khan
 
Windy City DB - Recommendation Engine with Neo4j
Windy City DB - Recommendation Engine with Neo4jWindy City DB - Recommendation Engine with Neo4j
Windy City DB - Recommendation Engine with Neo4jMax De Marzi
 
PyData NYC 2019
PyData NYC 2019PyData NYC 2019
PyData NYC 2019Li Jin
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversBrian Gesiak
 

Similar a Patrones de diseño (en Ruby) — RubyConf Uruguay 2010 (20)

Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scala
 
ScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin OderskyScalaDays 2013 Keynote Speech by Martin Odersky
ScalaDays 2013 Keynote Speech by Martin Odersky
 
The Joy Of Ruby
The Joy Of RubyThe Joy Of Ruby
The Joy Of Ruby
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
 
Ruby is an Acceptable Lisp
Ruby is an Acceptable LispRuby is an Acceptable Lisp
Ruby is an Acceptable Lisp
 
Design Patterns By Sisimon Soman
Design Patterns By Sisimon SomanDesign Patterns By Sisimon Soman
Design Patterns By Sisimon Soman
 
Origins of Elixir programming language
Origins of Elixir programming languageOrigins of Elixir programming language
Origins of Elixir programming language
 
Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python Domain Driven Design Made Functional with Python
Domain Driven Design Made Functional with Python
 
Lab 4
Lab 4Lab 4
Lab 4
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
 
Yin Yangs of Software Development
Yin Yangs of Software DevelopmentYin Yangs of Software Development
Yin Yangs of Software Development
 
Everything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-insEverything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-ins
 
Design patterns - Using Ruby
Design patterns - Using RubyDesign patterns - Using Ruby
Design patterns - Using Ruby
 
firststeps
firststepsfirststeps
firststeps
 
Windy City DB - Recommendation Engine with Neo4j
Windy City DB - Recommendation Engine with Neo4jWindy City DB - Recommendation Engine with Neo4j
Windy City DB - Recommendation Engine with Neo4j
 
PyData NYC 2019
PyData NYC 2019PyData NYC 2019
PyData NYC 2019
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 

Último

Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Último (20)

Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Patrones de diseño (en Ruby) — RubyConf Uruguay 2010

  • 1. Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/ Patrones de diseño (en ruby) Ignacio (Nacho) Facello @nachof nacho@nucleartesuji.com
  • 2.
  • 3. Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/ Patrones de diseño (en ruby) Ignacio (Nacho) Facello @nachof nacho@nucleartesuji.com
  • 4. Qué son patrones de diseño? ● Un patrón de diseño es una solución general reutilizable a un problema de común ocurrencia en el diseño de software (Wikipedia) ● Concepto originalmente usado en arquitectura (Christopher Alexander) ● Popularizado en el libro Design Patterns: Elements of Reusable Object-Oriented Software, popularmente conocido como GoF (Gang of Four), de Erich Gamma, Richard Helm, Ralph Johnson, y John Vlissides.
  • 5. Para qué sirven? ● Conocer una solución para un problema dado es útil cuando uno se enfrenta a ese problema. ● Nos dan un lenguaje común. ● Suelen resultar en un buen diseño
  • 6. Todo lo que sé de patrones lo aprendí jugando go
  • 9. … en diferentes contextos.
  • 10. Cuando no sirven... ● Que algo sea un patrón no quiere decir que sea adecuado. ● El contexto lo es todo.
  • 11. Lo importante: elegir la herramienta adecuada Photo by jannem http://www.flickr.com/photos/jannem/3312116875/
  • 13. Singleton require 'singleton' # From stdlib class SingletonExample include Singleton end one = SingletonExample.instance two = SingletonExample.instance puts one == two #=> true
  • 14. Observer require 'observer' # From stdlib class Car include Observable def initialize @fuel = 100 @speed = 0 end def run while @fuel > 0 do @speed += 1 @fuel -= 1 changed notify_observers (@speed, @fuel) end end end class SpeedWarner def initialize(car, speed_limit) @limit = speed_limit car.add_observer(self) end def update(speed, fuel) puts "Too fast!" if speed > @limit end end car = Car.new SpeedWarner.new(car, 70) FuelWarner.new(car, 10) car.run
  • 15. State require 'state_pattern' # Gem by @dcadenas # http://github.com/dcadenas/state_pattern class Stop < StatePattern::State def next sleep 3 transition_to (Go) end def color "Red" end end class Go < StatePattern::State def next sleep 2 transition_to (Caution) end def color "Green" end end class Caution < StatePattern::State def next sleep 1 transition_to (Stop) end def color "Amber" end end class TrafficSemaphore include StatePattern set_initial_state Stop end semaphore = TrafficSemaphore.new loop do puts semaphore.color semaphore.next end
  • 16. Adapter require 'forwardable' class LegacyClassA def some_method(a, b) puts "#{a}, #{b} (old A)" end end class LegacyClassB def do_something(b, a) puts "#{a}, #{b} (old B)" end end class AdapterA extend Forwardable def initialize(adaptee) @adaptee = adaptee end def_delegator :@adaptee, :some_method, :action end class AdapterB def initialize(adaptee) @adaptee = adaptee end def action(a, b) @adaptee.do_something(b, a) end end adapted_a = AdapterA.new(LegacyClassA.new) adapted_b = AdapterB.new(LegacyClassB.new) [adapted_a, adapted_b].each { | adapted| adapted.action("Hello", "World") }
  • 17. Iterator class ArrayIterator def initialize(array) @array = array @index = 0 end def first @index = 0 end def next @index += 1 end def current @array [@index] end def over? @index >= @array.size end end list = [1,2,3,4] iterator = ArrayIterator.new(list) while (!iterator.over?) do puts iterator.current iterator.next end
  • 18. Iterator class ArrayIterator def initialize(array) @array = array @index = 0 end def first @index = 0 end def next @index += 1 end def current @array [@index] end def over? @index >= @array.size end end list = [1,2,3,4] iterator = ArrayIterator.new(list) while (!iterator.over?) do puts iterator.current iterator.next end
  • 19. Mucho más sencillo... list = [1,2,3,4] list.each do |item| puts item end
  • 20. Otras formas de iterar list = [1,2,3,4] list.each do |item| puts item end list.map { |item| item * 2 } #=> [3,4,5,6] list.any? { |item| item == 2 } #=> true list.select { |item| item > 2 } #=> [3,4] list.detect { |item| item > 2 } #=> 3
  • 21. Strategy require 'forwardable' class Caveman extend Forwardable attr_accessor :strategy def initialize(strategy = DefaultStrategy.new) @strategy = strategy end def_delegator :@strategy, :survive def normal_day wake_up survive go_to_sleep end def wake_up puts "Waking up" end def go_to_sleep puts "Sleep now" end end class DefaultStrategy def survive puts "Hide from tigers" end end class AggressiveStrategy def survive puts "Grab spear, hunt tigers" end end class ConfusedStrategy def survive puts "Grab tiger, hunt spears" end end og = Caveman.new og.normal_day og.strategy = AggressiveStrategy.new og.normal_day
  • 22. Strategy (con lambdas) class Caveman attr_accessor :strategy def initialize(strategy = lambda { puts "Hide from tiger" }) @strategy = strategy end def normal_day wake_up survive go_to_sleep end def survive @strategy.call end def wake_up puts "Waking up" end def go_to_sleep puts "Sleep now" end end og = Caveman.new og.normal_day og.strategy = lambda { puts "Grab spear, hunt tiger" } og.normal_day
  • 23. Algunos usos ● Rails: Model-View-Controller ● ActiveRecord::Observer: Observer ● Array#sort: Strategy
  • 24. Algunos comentarios finales ● Stdlib y gemas son útiles ● Memorizarse los patrones y usarlos a cada oportunidad no ayuda. ● Entender sus consecuencias, y su porqué, sí sirve. ● “There may be a dozen different ways to implement a [given pattern] - it doesn't have to be done exactly like the GoF book or some web page.” Paul Wheaton (http://www.javaranch.com/patterns/)
  • 25.

Notas del editor

  1. Presentación De qué voy a hablar
  2. Presentación De qué voy a hablar
  3. Seguir slide, es sencilla
  4. Solución conocida a problema dado Lenguaje común, ejemplo observer “Mal” ejemplo: goto, o alguna otra cosa Buen diseño, siempre y cuando estemos hablando del contexto adecuado
  5. Va a ser una metáfora visual
  6. Secuencia de jugadas con un resultado parejo para ambos jugadores En este caso, blanco esquina, negro afuera
  7. Izquierda: negro trabaja bien Derecha: la pared de negro se enfrenta a blanco que lo neutraliza
  8. Lo más importante: el contexto.
  9. Es decir, elegir la herramienta adecuada para el problema actual es imprescindible
  10. Uno de los patrones más odiados. Tiene algunos casos de uso El ejemplo: porque el soporte está en stdlib — se encarga de temas de concurrencia y múltiples threads
  11. Permite que un objeto notifique a otros sobre cambios en su estado También soporte en stdlib Requerir &amp;apos;observer&amp;apos; En la clase observable, requerir Observable El método add_observer (en el initializer de los observers) agrega los observers al observable El método notify_observers en el observable llama al update de los observers, con los mismos argumentos. Pero sólo si antes llamamos a changed para avisarle
  12. Permite a un objeto cambiar su comportamiento de acuerdo a su estado interno (sin cambiar la interfaz) Hay muchas librerías que ayudan con State Elegí esta porque me parece clara Hasta le robé el ejemplo de código del readme Cada estado hereda de StatePattern::State El objeto incluye StatePattern Y define el estado inicial transition_to cambia el objeto estado Los métodos color y next son implícitamente delegados al objeto estado
  13. Hablando de delegar, hay varios patrones que usan delegación, no sólo State. Adapter, por ejemplo. Nos permite adaptar la interfaz de varias clases incompatibles a una misma interfaz que podemos usar. Para eso, es útil Forwardable En el caso de AdapterA, extiende Forwardable, y luego usa def_delegator. En el caso de AdapterB, no se puede, porque el orden de los parámetros es diferente
  14. Iterator nos permite recorrer una lista de objetos, como por ejemplo un array, para trabajar con ellos Implementación casi directa del GoF Para alguien que venga de Java, va a ser algo bastante conocido
  15. Pero en ese caso estás haciendo Java, no Ruby
  16. En Ruby hay formas más expresivas de lograr lo mismo Tenemos each para iterar sobre elementos
  17. Cuando iteramos con diferentes objetivos, es más expresivo iterar con métodos que expliquen qué es lo que queremos lograr Todos estos métodos están definidos en Enumerable Si tuviéramos otra estructura sobre la que iterar, con sólo implementar each e incluír el módulo Enumerable Ayer Aaron Patterson mostró un par de implementaciones para un árbol
  18. Permite cambiar la forma en la que un objeto se comporta Ejemplo medio clásico, con distintos objetos para cada Strategy Otra opción, tal vez más ruby, sería incluír módulos para cada Strategy diferente
  19. Me gusta más esta manera, parece más ruby
  20. Hay muchos usos de patrones que usamos todos los días, muchos que tenemos tan integrados que casi no nos damos cuenta Estos son sólo algunos ejemplos, hay muchos más si uno quiere buscar