Your SlideShare is downloading. ×
Ruby - Design patterns tdc2011
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Ruby - Design patterns tdc2011

2,581
views

Published on

Apresentação Sobre Design Patterns na trilha de Ruby/Python do TDC 2011 Floripa

Apresentação Sobre Design Patterns na trilha de Ruby/Python do TDC 2011 Floripa

Published in: Technology, Education

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,581
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
32
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Design Patterns + Ruby
  • 2. @rs_felix http://github.com/fellix http://www.crafters.com.br @crafterstudiohttp://blog.rollingwithcode.com
  • 3. Por que Ruby?
  • 4. 1995
  • 5. Erich Gamma, Richard Helm,Raph Johnson, John Vlissides
  • 6. “Gang of Four”
  • 7. Design Patterns
  • 8. Template Method
  • 9. class Relatorio def generate output_head output_body output_footer end def output_head end def output_body end def output_footer endend
  • 10. class Relatorio def generate output_head output_body output_footer end def output_head end def output_body end def output_footer endend
  • 11. class Relatorio def generate output_head Template output_body Method output_footer end def output_head end def output_body end def output_footer endend
  • 12. class HTMLRelatorio < Relatorio def output_head puts "<html><head> <title>Relatório HTML</title> </head>" end def output_body puts "<body>...</body>" end def output_footer puts "</html>" endend
  • 13. class HTMLRelatorio < Relatorio def output_head puts "<html><head> <title>Relatório HTML</title> </head>" end def output_body puts "<body>...</body>" end def output_footer puts "</html>" endend
  • 14. class HTMLRelatorio < Relatorio def output_head puts "<html><head> <title>Relatório HTML</title> </head>" end def output_body puts "<body>...</body>" end def output_footer puts "</html>" endend
  • 15. relatorio = HTMLRelatorio.newrelatorio.generate
  • 16. relatorio = HTMLRelatorio.newrelatorio.generate
  • 17. class Relatorio def generaterelatorio = HTMLRelatorio.new output_headrelatorio.generate output_body output_footer end end
  • 18. <html> <head><title>...</title></head> relatorio = HTMLRelatorio.new <body> relatorio.generate ... </body></html>
  • 19. Strategy
  • 20. Delegar ao invés de herdar
  • 21. class Formatter def format(text) endend
  • 22. class Formatter def format(text) raise "Abstract method" endend
  • 23. class HTMLFormatter < Formatter def format(text) puts "<html> " puts "<head> " puts "<title>...</title></head> " puts "<body>#{text}</body></html>" endend
  • 24. class HTMLFormatter < Formatter def format(text) puts "<html> " puts "<head> " puts "<title>...</title></head> " puts "<body>#{text}</body></html>" endend
  • 25. class HTMLFormatter def format(text) puts "<html> " puts "<head> " puts "<title>...</title></head> " puts "<body>#{text}</body></html>" endend
  • 26. Duck Typingclass HTMLFormatter def format(text) puts "<html> " puts "<head> " puts "<title>...</title></head> " puts "<body>#{text}</body></html>" endend
  • 27. class Relatorio def initialize(formatter) @formatter = formatter end def generate(text) @formatter.format(text) endend
  • 28. class Relatorio def initialize(formatter) @formatter = formatter end def generate(text) @formatter.format(text) endend
  • 29. class Relatorio def initialize(formatter) @formatter = formatter end def generate(text) @formatter.format(text) endend
  • 30. class Relatorio def initialize(formatter) @formatter = formatter Delegate end def generate(text) @formatter.format(text) endend
  • 31. relatorio = Relatorio.new(HTMLFormatter.new)relatorio.generate("Muitas e muitas coisas")
  • 32. relatorio = Relatorio.new(HTMLFormatter.new)relatorio.generate("Muitas e muitas coisas")
  • 33. relatorio = Relatorio.new(HTMLFormatter.new)relatorio.generate("Muitas e muitas coisas")
  • 34. Observer
  • 35. Manter-se informado sobre determinadas mudanças em objetos
  • 36. class NotaFiscal def pagar ... endend
  • 37. class FluxoCaixa def atualizar ... endend
  • 38. Consulta no bancoclass FluxoCaixa de dados todas as def atualizar notas pagas e ... atualiza o fluxo de end caixaend
  • 39. pagarNotaFiscal FluxoCaixa
  • 40. class NotaFiscal def pagar ... endend
  • 41. class NotaFiscal def pagar (fluxo) ... fluxo.atualizar endend
  • 42. class NotaFiscal def initialize (...) ... @observers = [] end def pagar ... endend
  • 43. class NotaFiscal def add_observer (observer) @observers << observer end def notify_observers @observers.each do |o| o.update(self) end endend
  • 44. class FluxoCaixa def atualizar ... end def update (nota_fiscal) ... endend
  • 45. fluxo_caixa = FluxoCaixa.newnota_fiscal = NotaFiscal.newnota_fiscal.add_observer fluxo_caixanota_fiscal.pagar
  • 46. require "observer"class NotaFiscal include Observable def pagar ... changed notify_observers(self) endend
  • 47. require "observer"class NotaFiscal include Observable def pagar ... changed notify_observers(self) endend
  • 48. require "observer"class NotaFiscal include Observable def pagar ... changed notify_observers(self) endend
  • 49. require "observer"class NotaFiscal include Observable def pagar ... changed notify_observers(self) endend
  • 50. require "observer"class NotaFiscal include Observable def pagar @changed = true ... changed notify_observers(self) endend
  • 51. require "observer" class NotaFiscal include Observable@observers.each { pagar def |o| o.update(object) } if @changed ... changed notify_observers(self) end end
  • 52. class FluxoCaixa def atualizar ... end def update (nota_fiscal) ... endend
  • 53. fluxo_caixa = FluxoCaixa.newnota_fiscal = NotaFiscal.newnota_fiscal.add_observer fluxo_caixanota_fiscal.pagar
  • 54. notificanota_fiscal fluxo_caixa = FluxoCaixa.new fluxo_caixa nota_fiscal = NotaFiscal.new nota_fiscal.add_observer fluxo_caixa nota_fiscal.pagar
  • 55. Factory
  • 56. Fornecer uma interface para a criação de objetos, sem especificar a classe concreta
  • 57. HTMLReader.new
  • 58. PDFReader.new
  • 59. class ReaderFactory def initialize (format) @reader_class = self.class.const_get("#{format}Reader") end def reader @reader_class.new endend
  • 60. class ReaderFactory def initialize (format) @reader_class = self.class.const_get("#{format}Reader") end def reader @reader_class.new endend
  • 61. class ReaderFactory def initialize (format) @reader_class = self.class.const_get("#{format}Reader") end def reader @reader_class.new endend
  • 62. class ReaderFactory def initialize (format) @reader_class = self.class.const_get("#{format}Reader") end def reader @reader_class.new endend
  • 63. html_reader = ReaderFactory.new("HTML").reader
  • 64. pdf_reader = ReaderFactory.new("PDF").reader
  • 65. class ReaderFactory def self.pdf_reader ReaderFactory.new("PDF").reader end def self.html_reader ReaderFactory.new("HTML").reader endend
  • 66. html_reader = ReaderFactory.html_reader
  • 67. Active Record Factory
  • 68. class Base ...end
  • 69. class Base def self.mysql_connection ... endend
  • 70. class Base def self.postgresql_connection ... endend
  • 71. adapter = "mysql"method_name = "#{adapter}_connection"Base.send(method_name, config)
  • 72. Builder
  • 73. Criar objetos complexos de forma legível, passo a passo
  • 74. class Pizza attr_accessor :massa, :molho, :coberturaend
  • 75. class PizzaBuilder attr_reader :pizza def initialize @pizza = Pizza.new endend
  • 76. class CalabresaBuilder < PizzaBuilder def molho @pizza.molho = "Tomate" end def massa @pizza.massa = "Pão" end def cobertura @pizza.cobertura = "queijo, calabresa" endend
  • 77. builder = CalabresaBuilder.newbuilder.molhobuilder.coberturabuilder.massapizza = builder.pizza
  • 78. pizza = CalabresaBuilder.new .molho .cobertura .massa .pizza
  • 79. class CalabresaBuilder < PizzaBuilder def molho @pizza.molho = "Tomate" self end def massa @pizza.massa = "Pão" self end def cobertura @pizza.cobertura = "queijo, calabresa" self endend
  • 80. builder = CalabresaBuilder.newbuilder.molho_and_coberturapizza = builder.pizza
  • 81. class PizzaBuilder def method_missing(name, *args) methods = name.to_s.split("_") return super(name, *args) unless methods[1] == "and" methods.each do |method| next if method == "and" send(method) end endend
  • 82. builder.molho_and_cobertura
  • 83. builder.massa_and_cobertura
  • 84. builder.molho_and_cobertura_and_massa
  • 85. Adapter
  • 86. Conectar objetos que não tem uma interface comum
  • 87. class Padrao1 def conectar (cabo) cabo.energizar endend
  • 88. class Padrao1 def conectar (cabo) cabo.energizar endend
  • 89. class CaboPadrao1 def energizar ... endend
  • 90. class Padrao2 def conectar (cabo) cabo.executar endend
  • 91. class Padrao2 def conectar (cabo) cabo.executar endend
  • 92. class CaboPadrao2 def executar ... endend
  • 93. class CaboPadrao2 def executar ... endend
  • 94. class CaboPadrao2 def executar tomada = Padrao2.new ... tomada.conectar end CaboPadrao2.newend
  • 95. class CaboPadrao2 def executar tomada = Padrao1.new ... tomada.conectar end CaboPadrao2.newend
  • 96. class CaboPadrao2 def executar tomada = Padrao1.new ... tomada.conectar end CaboPadrao2.newend
  • 97. class AdapterPadrao2 def initialize(cabo_padrao2) @cabo = cabo_padrao2 end def energizar @cabo.executar endend
  • 98. class AdapterPadrao2 def initialize(cabo_padrao2) @cabo = cabo_padrao2 end def energizar @cabo.executar endend
  • 99. class AdapterPadrao2 def initialize(cabo_padrao2) @cabo = cabo_padrao2 end def energizar @cabo.executar endend
  • 100. adapter = AdapterPadrao2.new(CaboPadrao2.new)tomada = Padrao1.newtomada.conectar(adapter)
  • 101. adapter = AdapterPadrao2.new(CaboPadrao2.new)tomada = Padrao1.newtomada.conectar(adapter)
  • 102. tomada adapter caboadapter = AdapterPadrao2.new(CaboPadrao2.new)tomada = Padrao1.newtomada.conectar(adapter)
  • 103. Proxy
  • 104. class ContaBancaria def initialize(saldo) @saldo = saldo end def depositar!(valor) @saldo += valor end def sacar!(valor) @saldo -= valor end def some_method endend
  • 105. class ContaBancariaProxy def initialize(conta_bancaria) @conta_bancaria = conta_bancaria end def depositar!(valor) @conta_bancaria.depositar! valor end def sacar!(valor) @conta_bancaria .sacar! valor endend
  • 106. Protection Proxy
  • 107. class ContaBancariaProxy def initialize(conta_bancaria) @conta_bancaria = conta_bancaria end def depositar!(valor) @conta_bancaria.depositar! valor end def sacar!(valor) @conta_bancaria .sacar! valor endend
  • 108. class ContaBancariaProxy def initialize(conta_bancaria, owner) @conta_bancaria = conta_bancaria @owner = owner end protected def check_access raise "Illegal Access" unless User. login == @owner endend
  • 109. class ContaBancariaProxy def depositar!(valor) check_access @conta_bancaria.depositar! valor end def sacar!(valor) check_access @conta_bancaria .sacar! valor endend
  • 110. Decorator
  • 111. class Coffee def price @price end def ingredients @ingredients endend
  • 112. class MilkDecorator def initialize (coffee) @coffee = coffee end def price coffee.price + 0.5 end def ingredients coffee.ingredients + ", Leite" endend
  • 113. class MilkDecorator def initialize (coffee) @coffee = coffee end def price coffee.price + 0.5 end def ingredients coffee.ingredients + ", Leite" endend
  • 114. class MilkDecorator def initialize (coffee) @coffee = coffee end def price coffee.price + 0.5 end def ingredients coffee.ingredients + ", Leite" endend
  • 115. class MilkDecorator def initialize (coffee) @coffee = coffee end def price coffee.price + 0.5 end def ingredients coffee.ingredients + ", Leite" endend
  • 116. coffee = Coffee.new(1.5, "Café, Água")puts coffee.ingredients
  • 117. coffee = Coffee.new(1.5, "Café, Água")puts coffee.ingredients Café, Água
  • 118. coffee = Coffee.new(1.5, "Café, Água")coffee = MilkDecorator.new coffeeputs coffee.ingredientsputs coffee.price
  • 119. coffee = Coffee.new(1.5, "Café, Água")coffee = MilkDecorator.new coffeeputs coffee.ingredients Café, Água, Leiteputs coffee.price
  • 120. coffee = Coffee.new(1.5, "Café, Água")coffee = MilkDecorator.new coffeeputs coffee.ingredientsputs coffee.price 2.0
  • 121. class ChocolateDecorator def initialize (coffee) @coffee = coffee end def price coffee.price + 1.0 end def ingredients coffee.ingredients + ", Chocolate" endend
  • 122. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffeeputs coffee.ingredients
  • 123. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffee Café, Água,puts coffee.ingredients Chocolate
  • 124. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffeeputs coffee.ingredients
  • 125. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffee
  • 126. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffeecoffee = MilkDecorator.new coffee
  • 127. coffee = Coffee.new(1.5, "Café, Água")coffee = ChocolateDecorator.new coffeecoffee = MilkDecorator.new coffee Café, Água,puts coffee.ingredients Chocolate, Leite
  • 128. Singleton
  • 129. Garantir que só haja uma instancia de determinado objeto
  • 130. @count
  • 131. @count@@count
  • 132. class CountTester @@count = 0 def initialize @count = 0 end def self.increment @@count++ end def increment @count++ endend
  • 133. class CountTester Variável @@count = 0 Global def initialize @count = 0 end def self.increment @@count++ end def increment @count++ endend
  • 134. class CountTester @@count = 0 def initialize Variável @count = 0 Local end def self.increment @@count++ end def increment @count++ endend
  • 135. class CountTester @@count = 0 def initialize @count = 0 end Metódo def self.increment Estático @@count++ end def increment @count++ endend
  • 136. class CountTester @@count = 0 def initialize @count = 0 end def self.increment @@count++ end Metódo de def increment Instância @count++ endend
  • 137. class CountTester Variável COUNT = 0 Globalend
  • 138. class Logger @@instance = Logger.new def self.instance @@instance endend
  • 139. logger1 = Logger.instancelogger2 = Logger.instance
  • 140. logger = Logger.new
  • 141. class Logger @@instance = Logger.new def self.instance @@instance endend
  • 142. class Logger @@instance = Logger.new def self.instance @@instance end private_class_method :newend
  • 143. require "singleton"class Logger include Singletonend
  • 144. logger = Logger.new
  • 145. logger = Logger.new private method ‘new’ called for Logger::Class
  • 146. logger = Logger.instance
  • 147. Obrigado @rs_felix http://github.com/fellix http://www.crafters.com.br @crafterstudiohttp://blog.rollingwithcode.com

×