Design patterns: resolvendo problemas comuns (ruby)
-
Upload
michael-castillo-granados -
Category
Technology
-
view
440 -
download
5
description
Transcript of Design patterns: resolvendo problemas comuns (ruby)
Design Patternsresolvendo problemas comuns
Agenda
● Gang of Four (GoF)● O que é design pattern● Tipos de padrões
○ template method○ strategy○ observer○ composite○ iterator
● Ordem do livro○ template○ strategy○ observer○ composite○ iterator○ command○ adapter○ proxy○ decorator○ singleton○ factory○ builder○ interpreter
Gang of Four (GoF)
O que seria Gang of Four?
Gang of Four (GoF)
talvez...
Gang of Four (GoF)
nããããão...
Gang of Four (GoF)
O Gang of Four são os autores do livro "Design Patterns: Elements of Reusable Object-Oriented Software". Este importante livro descreve várias técnicas de desenvolvimento e armadilhas, além de fornecer vinte e três padrões de projeto de programação orientadas a objeto. Os quatro autores foram Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides.
— Richard Carr (blackwasp.co.uk)
O que é design pattern?
(…) Design Pattern, descreve uma solução geral reutilizável para um problema recorrente no desenvolvimento de sistemas de software orientados a objetos.
— wikipedia (sic)
Gang of Four (GoF)
Debate sugerido
Gang of Four (GoF)
Debate sugeridoSepare as coisas que mudam das coisas que são sempre as mesmas
Gang of Four (GoF)
Debate sugeridoPrograme para uma interface e não para uma implementação
Gang of Four (GoF)
Debate sugeridoPrefira composição ao no lugar de herança
Gang of Four (GoF)
Debate sugeridoDelegue, delegue, delegue
●○ factory method○ prototype○
●○ facade○ flyweight○ composite○ decorator○ proxy
●○ chain of responsibility○ mediator○ memento○ state○ visitor○ template method
●○ factory method○ prototype○
●○ facade○ flyweight○ composite○ decorator○ proxy
●○ chain of responsibility○ mediator○ memento○ state○ visitor○ template method
● Padrões de Criação○ factory○ builder○ singleton
● Padrões estruturais○ adapter○ bridge○ composite○ decorator○ proxy
● Padrões comportamentais○ command○ interpreter○ iterator○ observer○ strategy○ template method
Tipos de padrões
●○ abstract factory○ builder○ singleton
●○ adapter○ bridge○ composite○ decorator○ proxy
●○ command○ interpreter○ iterator○ observer○ strategy○ template method
●○ factory method○ prototype○
●○ facade○ flyweight○ composite○ decorator○ proxy
●○ chain of responsibility○ mediator○ memento○ state○ visitor○ template method
●○ factory method○ prototype○
●○ facade○ flyweight○ composite○ decorator○ proxy
●○ chain of responsibility○ mediator○ memento○ state○ visitor○ template method
● Padrões de Criação○ factory○ builder○ singleton
● Padrões estruturais○ adapter○ bridge○ composite○ decorator○ proxy
● Padrões comportamentais○ command○ interpreter○ iterator○ observer○ strategy○ template method
Tipos de padrões
●○ abstract factory○ builder○ singleton
●○ adapter○ bridge○ composite○ decorator○ proxy
●○ command○ interpreter○ iterator○ observer○ strategy○ template method
●○ abstract factory○ builder○ singleton
●○ adapter○ bridge○ composite○ decorator○ proxy
●○ command○ interpreter○ iterator○ observer○ strategy○ template method
o que veremos hoje
O problema:O script precisa de uma alteração em uma determinada parte do processo para que seja usada de outra forma dependendo de sua apliação
template method
Como resolverclass Report
// define header, output_line and footer as raised
def report()
header
@lines.each do |line|
output_line line
end
footer
end
end
class HTMLReport < Report
# implement header, output_line and footer methods
end
class PlainReport < Report
# implement header, output_line and footer methods
end
strategy
O problema:Apesar do template method resolver o problema de forma simples e direta às vezes queremos mudar grande parte do script
Como resolverclass Consessionaria
attr_reader :loja, :carros
attr_accessor :testador
def initialize(testador)
@loja = "Importados Classic"
@carros = ["Ferrari", "Lamborghini", "BMW", "Chevrolet"]
@testador = testador
end
def fazer_test_drive
@testador.fazer_test_drive(@loja, @carros)
end
end
class Test_Drive
def fazer_test_drive(loja, carros)
puts "> #{loja}"
carros.each do |carro|
puts "Testando #{carro}..."
end
end
end
observer
O problema:Integrar vários objetos a apenas um para que eles executem determinada ação a partir da ação executada pelo primeiro objeto
Como resolverclass Funcionario def initialize(nome, salario) @nome = nome @salario = salario @observers = [] end def salario=(novo_salario) @salario = novo_salario notify_observers end def notify_observers @observers.each do |observer| observer.update self end end def add_observer(observer) @observers << observer end def remove_observer(observer) @observer.remove(observer) endend
composite
O problema:Criar uma estrutura em forma de árvore a fim de poder adicionar ou remover tarefas em cascata, desta forma o código se torna mais limpo e de fácil compreensão
Como resolverclass Tarefa attr_reader :nome def initialize(nome) @nome = nome end def tempo_requerido 0.0 endend
class AdicionarIngredientes < tarefa def initialize super "Adicionar ingredientes" end def tempo_requerido 1.0 endend
class BaterIngredientes < Tarefa def initialize super "Bater ingredientes" end def tempo_requerido 3.0 endend
class CompositeTask < Tarefa def initialize(name) super name @sub_tarefas = [] end def adiciona_sub_tarefa(tarefa) @sub_tarefas << tarefa end def remove_sub_tarefa(tarefa) @sub_tarefas.delete(tarefa) end def tempo_requerido tempo = 0 @sub_tarefas.each do |tarefa| tempo += tarefa.tempo_requerido end tempo endend
class BaterBolo < CompositeTask def initialize super "Bater o Bolo" adiciona_sub_tarefa AdicionarIngredientes.new adiciona_sub_tarefa BaterIngredientes.new endend
iterator
O problema:Criar uma estrutura de objetos similares em forma de coleção a fim de poder acessar todos de uma só vez
Como resolver# external
class ArrayIterator def initialize(array) @array = array @index = 0 end def has_next? @index < @array.length end def item @array[@index] end def next_item value = @array[@index] @index++ value endend
array = ["Michael", "Alice", "Lyssa"]i = ArrayIterator(array)while i.has_next? puts "Pessoa: #{i.next_item}"end
# internal
def roll_all_elements(array) i = 0 while i < array.length yield array[i] i += 1 endend
a = ["Milfont", "Demis", "Enzo"]roll_all_elements(a) {|p| puts "Pessoa: #{p}" }
referencias
Design Patterns In Ruby — Russ Olsenhttp://blackwasp.co.uk/GofPatterns.aspxhttp://sourcemaking.com/design_patterns/http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_softwarehttps://github.com/nslocum/design-patterns-in-ruby
Obrigado!