Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/
Patrones de diseño
(en ruby)
Ignacio (Nacho) Facello...
Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/
Patrones de diseño
(en ruby)
Ignacio (Nacho) Facello...
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
e...
Para qué sirven?
● Conocer una solución para un problema dado
es útil cuando uno se enfrenta a ese problema.
● Nos dan un ...
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
t...
Observer
require 'observer' # From stdlib
class Car
include Observable
def initialize
@fuel = 100
@speed = 0
end
def run
w...
State
require 'state_pattern' # Gem by
@dcadenas
# http://github.com/dcadenas/state_pattern
class Stop < StatePattern::Sta...
Adapter
require 'forwardable'
class LegacyClassA
def some_method(a, b)
puts "#{a}, #{b} (old A)"
end
end
class LegacyClass...
Iterator
class ArrayIterator
def initialize(array)
@array = array
@index = 0
end
def first
@index = 0
end
def next
@index ...
Iterator
class ArrayIterator
def initialize(array)
@array = array
@index = 0
end
def first
@index = 0
end
def next
@index ...
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....
Strategy
require 'forwardable'
class Caveman
extend Forwardable
attr_accessor :strategy
def initialize(strategy =
DefaultS...
Strategy (con lambdas)
class Caveman
attr_accessor :strategy
def initialize(strategy = lambda { puts "Hide from tiger" })
...
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.
...
Gracias :-)
Patrones de diseño (en Ruby) — RubyConf Uruguay 2010
Patrones de diseño (en Ruby) — RubyConf Uruguay 2010
Upcoming SlideShare
Loading in …5
×

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

2,249 views

Published on

Published in: Technology
  • Be the first to comment

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

  1. 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. 2. Photo by lucynieto http://www.flickr.com/photos/lucynieto/2299831355/ Patrones de diseño (en ruby) Ignacio (Nacho) Facello @nachof nacho@nucleartesuji.com
  3. 3. 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.
  4. 4. 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
  5. 5. Todo lo que sé de patrones lo aprendí jugando go
  6. 6. Joseki
  7. 7. El mismo joseki...
  8. 8. … en diferentes contextos.
  9. 9. Cuando no sirven... ● Que algo sea un patrón no quiere decir que sea adecuado. ● El contexto lo es todo.
  10. 10. Lo importante: elegir la herramienta adecuada Photo by jannem http://www.flickr.com/photos/jannem/3312116875/
  11. 11. Algunos ejemplos de patrones en Ruby
  12. 12. Singleton require 'singleton' # From stdlib class SingletonExample include Singleton end one = SingletonExample.instance two = SingletonExample.instance puts one == two #=> true
  13. 13. 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
  14. 14. 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
  15. 15. 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") }
  16. 16. 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
  17. 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. 18. Mucho más sencillo... list = [1,2,3,4] list.each do |item| puts item end
  19. 19. 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
  20. 20. 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
  21. 21. 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
  22. 22. Algunos usos ● Rails: Model-View-Controller ● ActiveRecord::Observer: Observer ● Array#sort: Strategy
  23. 23. 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/)
  24. 24. Gracias :-)

×