design patterns: resolvendo problemas comuns (ruby)

Post on 24-May-2015

440 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

Tech-talk no R7 sobre alguns design patterns para utilizar no dia-a-dia em Ruby.

TRANSCRIPT

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}" }

Obrigado!

top related