Você está na página 1de 64

VINICIUS VIVAN

O G U I A
R A D O D O S
ILUS T
P A T T E R N S
DESIG N
APRENDA DE FORMA FÁCIL E VISUAL

Rabiscando
PADRÕES DE
PROJETO
"The only way to go fast is to go well"
"A única forma de ir rápido é ir certo"
Robert Cecil Martin POO
(Uncle Bob)

ENTENDA COMO OS DESIGN PATTERNS VÃO TE AJUDAR A


CRIAR CÓDIGOS SUSTENTÁVEIS.

designpatterns.com.br 2
Prezado leitor,
Muito obrigado por ter baixado este e-book e me dar a honra de te ajudar a
aprender Design Patterns.

Meu nome é Vinicius Vivan, sou cientista da computação e atuo como


desenvolvedor de software desde 2014.

Durante a minha jornada até aqui, um dia, assim como você, eu decidi estudar
Design Patterns e me deparei com um assunto muito vasto, complexo e com
pouquíssimo material de qualidade sobre o assunto. POO
Tudo o que eu encontrava era complexo demais ou não se aprofundava nos
detalhes de forma satisfatória.

Decidi explicar Design Patterns de uma forma fácil e completa para quem
Vinicius Vivan estivesse interessado no assunto. Criei o material que um dia eu desejei
Cientista da computação encontrar e agora ele está aqui de graça pra você.
e autor deste ebook
Bons Estudos!

designpatterns.com.br 3
Dê um Zoom
e
Leia Devido a limitação de espaço, alguns textos
desse e-book podem ter ficados pequenos.

Você não precisa se preocupar com isso,


todo o conteúdo é vetorizado. Isso significa
que você pode dar zoom à vontade sem que
as imagens e textos percar qualidade.

Use e abuse desse recurso :)

POO

designpatterns.com.br 5
ATENÇÃO
Antes de avançar nesse e-book é preciso
que você saiba de algumas coisas.

Esse material é direcionado à profissionais que possuem


alguma experiência com programação orientada a objetos.

POO
Para garantir que a maioria dos leitores tenham o
conhecimento básico necessário, foi disponibilizado o
módulo 00 que é um NIVELADOR de conhecimentos.

Nele você encontrará duas video aulas que te darão o


embasamento necessário para finalmente dominar os
Design Patterns.

designpatterns.com.br 4
MÓDULO 00

Nivelamento
POO

designpatterns.com.br 6
Nivelamento
REVISÃO DE CONCEITOS FUNDAMENTAIS DE
PROGRAMAÇÃO ORIENTADA A OBJETOS

APERT
E Você vai revisar:
Y
O PLA
As definições de classe, classe abstrata, métodos,
POO
métodos abstratos, objetos e interfaces.

O que é um diagrama de classes e alguns dos


relacionamentos entre classes (Associação,
Generalização, Realização, Agregação e Composição).

Os pilares da orientação a objetos (Encapsulamento,


Herança, Abstração e Polimorfismo).

designpatterns.com.br 7
Nivelamento
O QUE SÃO PADRÕES DE PROJETO
(DESIGN PATTERNS)

APERT
E Você vai aprender:
Y
O PLA
O que são padrões de projeto.
POO
O que e quais são os padrões criacionais.

O que e quais são os padrões Estruturais.

O que e quais são os padrões comportamentais.

designpatterns.com.br 8
MÓDULO 01
PADRÃO CRIACIONAL

Singleton
POO

"Um objeto
e nada mais"
designpatterns.com.br 9
Singleton
A DEFINIÇÃO
O padrão Singleton garante que uma classe tenha apenas uma
instância e fornece um ponto global de acesso a ela.

O EXEMPLO
POO
Para evitar conexões desnecessárias, deseja-se criar uma única
Única instância da instância de um objeto de conexão com o banco de dados.
conexao classe Conexao

Tal instância será compartilhada por todos os objetos que


precisarem se conectar ao banco de dados.
Objeto 1
Objeto 5

Objeto 2 Objeto 4
Objeto 3

designpatterns.com.br 10
Singleton
ATENÇÃO: O singleton é
Conexao considerado um anti-pattern.
Sua utilização requer muita
instancia: Conexao | null cautela.

construtor() Única instância da


this.instancia = null;
classe Conexao
getInstancia(): Conexao conexao
O método construtor da classe
Conexao deve ser privado. Isso
significa que só é possível criar
objetos da classe Conexao de if (this.instancia == null) { Objeto
Objeto
dentro dela. this.instancia = new Conexao();
return this.instancia;
}
Objeto Objeto
Objeto
return this.instancia;

Existirá somente um único objeto conexao em todo o sistema. O método getInstancia


garante que somente uma instancia de Conexao será criada. Todos os objetos que
precisarem da conexao deverão acessar o mesmo objeto.

designpatterns.com.br 11
Singleton DIAGRAMA DE CLASSES
ILUSTRADO
1
ClienteA Conexao
Talvez você esteja se perguntando o motivo do Singleton con: Conexao
estar nesse e-book, já que ele é considerado um anti- instancia: Conexao | null 2
pattern. Os motivos são muito simples:
5 construtor() 3
1) Existe um conceito muito interessante por trás do
Singleton. Somente isso já justificaria a presença dele por this.con = Conexao.getInstancia(); getInstancia(): Conexao 4
aqui.

2) Esse e-book foi escrito para desenvolvedores. Pode ser 1


ClienteB A classe Conexao é o Singleton. Existirá
que você tenha que dar manutenção em um código legado
somente UMA INSTANCIA dessa classe em
que tenha o Singleton por lá (muitos frameworks mais
con: Conexao todo o sistema. Tal instância será um
antigos se baseiam neste padrão). É muito mais seguro que
recurso compartilhado.
você entenda o Singleton para saber exatamente quais
cuidados deve tomar. 6
2
3) O Singleton tem outras utilidades além da garantia de A classe Conexao possui um atributo que
this.con = Conexao.getInstancia(); guarda a única instância da classe. Esse
criação de um único objeto. Imagine que você tenha que
atributo pode ser NULL ou do próprio tipo da
trabalhar com a limitação de instanciações de um 4 classe.
determinado objeto. O Singleton pode atuar como um O método getInstancia é o responsável por controlar o
contador de instâncias. Se você souber gerenciar os riscos e processo de criação do objeto Singleton.
consequências, o Singleton ainda pode ser muito útil. 3
Na primeira vez que o método é invocado, o objeto do A classe Conexao possui o construtor
5 tipo Conexao é instanciado, armazenado no atributo PRIVADO. Deste modo, somente a própria
instancia da classe Conexao, depois retornado e classe pode criar um objeto dela mesma.
guardado no atributo con de ClienteA.
Código do método
if (this.instancia == null) { Nenhuma outra classe além de Conexao
getInstancia. this.instancia = new Conexao(); A partir da segunda chamada, o método getInstancia
pode criar um objeto do tipo Conexao.
return this.instancia; apenas retorna o objeto que foi previamente
} 6 armazenado no atributo instancia da classe Conexao.
Após o retorno a instância retornada é armazenada no new Conexao();
return this.instancia; atributo con de ClienteB.

designpatterns.com.br 12
MÓDULO 02
PADRÃO COMPORTAMENTAL

Stratregy
POO

"Fazendo a mesma coisa


de jeitos diferentes"
designpatterns.com.br 13
Strategy
A DEFINIÇÃO
O padrão de projeto Strategy define uma família de algoritmos, encapsula
cada um deles e os torna intercambiáveis. O Strategy permite que o
algoritmo varie independentemente dos clientes que o utilizam.
Obs: Intercambiáveis significa que um pode ser trocado pelo outro.

POO
O EXEMPLO
Deseja-se criar uma calculadora de inteiros que possa ter as
operações facilmente expandidas.
Cada operação é um algoritmo que faz a mesma coisa, realiza um calculo
entre dois inteiros, porém, cada operação faz isso de formas diferentes

+ - * / ?
designpatterns.com.br 14
Strategy
Qualquer uma dessas operações podem ser
Tenho 2 números para calcular. utilizadas da mesma forma pela calculadora. Elas Podem existir quantas operações
podem ser facilmente substituídas umas pelas forem necessárias. Todas dever ter
preciso de alguma operação. outras. Isso é a mesma coisa que dizer que elas são o método calcular
intercambiáveis.
Pode ser qualquer uma. Sei que todos os

+ - / ?
membros da família de operações sabem

*
calcular números.

POO

Família de Operações
(Família de algoritmos)
É obrigatório que todo membro dessa família tenha o método

calcular(operandoA, operandoB)

designpatterns.com.br 15
Strategy DIAGRAMA DE CLASSES
ILUSTRADO

1
Calculadora <<interface>> 3
Operacao Família de Operações
operandoA: int (Família de algoritmos)
calcular(operandoA, operandoB)
operandoB: int
operacao: Operacao

4 4 4 4
Soma Subtracao Multiplicacao Divisao
setOperacao(Operacao operacao)

calcularOperacao() calcular(operandoA, operandoB) calcular(operandoA, operandoB)

calcular(operandoA, operandoB)

this->operacao = operacao; + - calcular(operandoA, operandoB)

/
2 return operandoA + OperandoB; return operandoA - OperandoB * return operandoA / OperandoB

return operacao->calcular(this.operandoA, this.OperandoB); 2 return operandoA * OperandoB


O método setOperacao
1 É um Setter, ele é o responsável por dizer à Calculadora
A Calculadora é o cliente que utiliza o padrão de projeto qual Operacao utilizar.
3 4
Strategy. O método calcularOperacao Operacao é a interface ou classe que define o
Os métodos cinza São a implementações
É o responsável por invocar o método calcular do objeto comportamento de cada estratégia (strategy). Em outras concretas das
atribuído ao atributo operacao por meio do método Setter. palavras, para fazer parte da família de Operações têm estratégias. No nosso
Exemplo que segui as regras definidas em Operacao. contexto cada classe
São métodos exclusivos da Calculadora, eles não fazem parte do
s = new Soma(); O método calcular implementa uma
padrão Strategy. Eles representam as demais funcionalidades this->operacao = s
que sua classe pode ter, ai no seu dia a dia de trabalho. operação diferente. Ao
s->calcular(operandoA, OperandoB) trocar a classe
É o que dita o comportamento que deve ser
A classe calculadora possui os atributos operandoA, operandoB Estaremos chamando o método calcular da classe (operação), trocamos o
implementado por todas as estratégias concretas. No
Soma. comportamento.
e operacao. return operandoA + OperandoB nosso caso, calcular operações.

designpatterns.com.br 16
MÓDULO 03
PADRÃO CRIACIONAL

Factory Method POO

"Criar um objeto não é


problema meu"
designpatterns.com.br 17
Factory Method
A DEFINIÇÃO
O Padrão Factory Method define uma interface para criar um objeto,
mas permite que a subclasses possam decidir qual classe instanciar,
possibilitando que uma classe seja capaz de prorrogar a instanciação
de uma classe para subclasses.

O EXEMPLO POO
Criar um objeto manequim com uma peça de roupa.

designpatterns.com.br 18
Factory Method
A classe Manequim precisa
de um objeto do tipo Roupa.
<<inteface>>
Cliente Manequim Roupa
Dependência
roupa: Roupa

criarRoupa(string parteDoCorpo): Roupa


Camiseta
A classe Manequim é a responsável
pela criação de um objeto do tipo
switch (parteDoCorpo) { As classes Camiseta,
Roupa.
case 'tronco': Bermuda e Tenis
return new Camiseta(); implementam a interface
O método criarRoupa retorna um
case 'pernas': Roupa. Portanto, graças a Bermuda
objeto diferente de acordo com a parte
return new Bermuda(); abstração, também são
do corpo passada por parâmetro.
case 'pes': do tipo Roupa.
return new Tenis();
troco: Retorna um objeto Camiseta; }
pernas: Retorna um objeto Bermuda;
Tenis
pes: Retorna um objeto Tenis.

Qual é o problema aqui? Imagine que ao invés de uma classe, existam 5 classes que precisem de um objeto
Roupa. Esse switch case iria se repetir em todas as classes. As regras para criar um objeto Roupa estariam
espalhadas por todo o sistema.

designpatterns.com.br 19
Factory Method
VAMOS DEIXAR AS COISAS MAIS INTERESSANTES
Considere que agora existam dois estilos de roupa: Formal e Causal. Podemos criar dois métodos na classe Manequim, um que cria roupas formais e outro que
cria roupas casuais.

<<inteface>>
Cliente
Manequim Roupa
Dependência
roupa: Roupa

Exemplo de uma classe Cliente Utilizando o método criarRoupaFormal(string parteDoCorpo): Roupa


utilizando a classe Manequim. criarRoupaFormal Camisa Camiseta
criarRoupaCasual(string parteDoCorpo): Roupa

manequim = new Manequim();

roupa = manequim.criarRoupaFormal('tronco'); switch (parteDoCorpo) { switch (parteDoCorpo) {


/*supondo que Manequim possui um método setter*/ case 'tronco': case 'tronco':
manequim.setRoupa(roupa); return new Camisa(); return new Camiseta();
case 'pernas': case 'pernas': Calcas Bermuda
return new Calcas(); return new Bermuda();
roupa = manequim.criarRoupaFormal('pernas'); case 'pes': case 'pes':
manequim.setRoupa(roupa); return new Sapatos(); return new Tenis();
} }

Esse método cria roupas Esse método cria roupas


manequim = new Manequim(); formais. casuais. Sapatos Tenis

roupa = manequim.criarRoupaCasual('tronco');
/*supondo que Manequim possui um método setter*/
manequim.setRoupa(roupa);

Métodos diferentes resultam em objetos


diferentes.
roupa = manequim.criarRoupaCasual('pernas');
manequim.setRoupa(roupa);
Toda a lógica de criação das roupas continua na
classe Manequim.

Utilizando o método
criarRoupaCasual

designpatterns.com.br 20
Factory Method
Retomando a definição: O Padrão Factory Method define uma interface para
criar um objeto, mas permite que as subclasses possam decidir qual classe
instanciar, possibilitando que uma classe seja capaz de prorrogar a instanciação Os dois métodos da classe Manequim foram
de uma classe para subclasses. substituídos por um método abstrato. Repare
que o método CriarRoupa recebe o mesmo
parâmetro e possui o mesmo tipo de retorno
que os métodos anteriores.
por ter um método abstrato, Manequim se
criarRoupa é um
torna uma classe abstrata. <<inteface>>
método abstrado, Roupa
então, as subclases de Dependência
Manequim deverão Manequim
implementar esse
método. roupa: Roupa
Esse método é a interface
Camisa Camiseta
para criar um objeto citada
Factory Method criarRoupa(string parteDoCorpo): Roupa na definição.

Herança Herança
Calcas Bermuda
ManequimFormal ManequimCasual

criarRoupa(string parteDoCorpo): Roupa criarRoupa(string parteDoCorpo): Roupa

Detalhes interessantes: Sapatos Tenis


switch (parteDoCorpo) { switch (parteDoCorpo) {
Aqui as Fabricas são os
case 'tronco': case 'tronco':
métodos das subclasses e Conforme diz a definição,
return new Camisa(); return new Camiseta();
não as subclasses. O as subclasses decidem
case 'pernas': case 'pernas':
padrão Factory Method quais classes são
utiliza Herança como return new Calcas(); instanciadas. return new Bermuda();
recurso para diferenciar case 'pes': case 'pes': A classe Manequim foi subclassificada em
as maneiras que os return new Sapatos(); return new Tenis(); ManequimFormal e ManequimCasual. Tais subclasses
objetos são criados. } } implementam de forma concreta o método criarRoupa,
que por sua vez é o Factory Method.

designpatterns.com.br 21
Factory Method
<<inteface>>
Roupa
Manequim
Dependência
Cliente roupa: Roupa

criarRoupa(string parteDoCorpo): Roupa Factory Method Camisa Camiseta

Herança Herança

ManequimFormal ManequimCasual
Calcas Bermuda
criarRoupa(string parteDoCorpo): Roupa criarRoupa(string parteDoCorpo): Roupa

Sapatos Tenis
manequim = new ManequimFormal(); manequim = new ManequimCasual();

Exemplo de uma roupa = manequim.criarRoupa('tronco'); roupa = manequim.criarRoupa('tronco');


/*supondo que Manequim possui um método setter*/ /*supondo que Manequim possui um método setter*/
classe Cliente
manequim.setRoupa(roupa); manequim.setRoupa(roupa);
utilizando as
subclasses de Subclasses diferentes
Manequim. roupa = manequim.criarRoupa('pernas'); roupa = manequim.criarRoupa('pernas'); resultam em objetos
Utilizando a subclasse
manequim.setRoupa(roupa); manequim.setRoupa(roupa); diferentes.
ManequimCasual
Utilizando a subclasse
ManequimFormal Toda a lógica de criação
das roupas fica nas
subclasses (Factories).

designpatterns.com.br 22
Factory Method DIAGRAMA DE CLASSES
ILUSTRADO
1 3 4
Cliente
A classe Manequim é uma classe Abstrata. ela É o tipo abstrato do objeto retornado pelo São as classes concretas que implementam
possui um método abstrato que define a Factory Method. Podemos dizer que Roupa é Roupa. Ou seja, são as classes cujo os
interface para a criação de um objeto. Tal o PRODUTO produzido pelo Factory Method. objetos serão de fato instanciados e
método é o Factory Method e será retornados pelo Factory Method.
implementado pelas subclasses de Manequim.

1 <<inteface>> 3
Manequim Roupa
Dependência Abstrata
roupa: Roupa

criarRoupa(string parteDoCorpo): Roupa Factory Method


4 4
Camisa Camiseta

Herança Herança
2 2
ManequimFormal ManequimCasual

criarRoupa(string parteDoCorpo): Roupa criarRoupa(string parteDoCorpo): Roupa 4 Calcas


4 Bermuda

Dependência Concreta

2 4 4
Sapatos Tenis
As subclasses de Manequim ditam como e qual objeto
será criado pela implementação concreta do Factory
Method (criarRoupa).

Ao escolher a subclasse, também se escolhe o


comportamento do Factory Method. Dependência Concreta

designpatterns.com.br 23
MÓDULO 04
PADRÃO CRIACIONAL

Abstract Factory POO

"Criar um grupo de objeto


não é problema meu"
designpatterns.com.br 24
Abstract Factory
A DEFINIÇÃO
O padrão Abstract Factory fornece uma interface para criar famílias de
objetos relacionados ou dependentes, sem especificar suas classes
concretas.

O EXEMPLO POO
Criar um meio para que um objeto manequim possa ser vestido
com peças de roupas para o tronco e pernas e sapatos.

As peças de roupas devem ser coerentes com a ocasião. São


elas: formal e casual. Além disso o sistema deve ficar aberto a
novas ocasiões.

designpatterns.com.br 25
Abstract Factory
Enquanto o padrão Factory Method fornece uma interface para a criação de objetos, o padrão Abstract
Factory fornece uma interface para criar uma família de objetos.

Em outras palavras, o Abstract Factory fornece uma interface para a criação de objetos que
fazem sentido juntos. Além disso, membros de uma família de objetos não devem se misturar
com membros de outras famílias.
<<inteface>>
Considere as mesmas classes de roupas Roupa

que utilizamos no padrão Factory Method.

Aqui temos duas famílias de objetos: Camisa Camiseta ATENÇÃO: Para entender o
Traje Formal Abstract Factory recomendo
Traje Casuais que já tenha entendido o
padrão Factory Method.

Calcas Bermuda

Traje Formal Traje Casual

Peças de roupas formais


não devem se misturar
Sapatos Tenis Peças de roupas casuais não devem
com peças de roupas se misturar com peças de roupas
casuais. formais.

designpatterns.com.br 26
Abstract Factory
Factory Method Abstract Factory

Manequim A classe Manequim espera apenas objetos do tipo Roupa. A classe Manequim espera 3 tipos diferentes de objetos, uma
Não existe distinção do tipo de roupa que cada parte do Manequim para cada parte do corpo.
manequim recebe.
tronco: Roupa tronco: RoupaTronco As Factories deve criar 3 objetos, um de cada tipo.
pernas: Roupa As Factories devem montar um manequim que faça pernas: RoupaPernas
pes: Roupa sentido, mas não existe controle explicito de tipos. Existe pes: RoupaPes Em nosso contexto uma famíla é composta por 1 objeto do tipo
apenas uma convenção que cada factory sabe como criar RoupaTronco, 1 do tipo RoupaPernas e outro do tipo
determinados objetos, no nosso caso, Manequim. RoupaPes.

As Factories devem controlar os tipos de forma explícita.

Objetos de um único tipo


Familia Traje
<<interface>>
Roupa RoupaTronco RoupaPenas RoupaPes

Objetos de tipos diferentes


Camisa Camiseta
Camisa <<interface>> Camiseta
RoupaTronco

Calcas Bermuda
Calcas <<interface>> Bermuda
RoupaPernas

Sapatos Tenis Sapatos <<interface>> Tenis


RoupaPes

designpatterns.com.br 27
Abstract Factory
Factory Method Abstract Factory

Manequim <<interface>>
Manequim RoupaTronco
<<interface>> tronco: RoupaTronco
tronco: Roupa Roupa pernas: RoupaPernas
pernas: Roupa pes: RoupaPes
pes: Roupa <<interface>>
RoupaPernas

<<interface>>
RoupaPes
Aqui nós temos um método abstrato que TrajeFactory
ManequimFactory
cria um objeto.

factoryMethod(): Manequim criarRoupaTronco(): RoupaTronco


Portanto Factory Method (Método Fabrica)
criarRoupaPernas(): RoupaPernas Aqui nós temos uma Classe abstrata com
métodos abstratos que retornam tipos
criarRoupaPes(): RoupaPes abstratos
A intenção do Factory Method é encapsular o processo de
Cada um dos métodos é responsável por criar
criação de 1 objeto.
A intenção do Abstract Factory é um membro da família de objetos (Família
encapsular o processo de criação Traje)
de 1 Familia de objetos. Portanto
mais de 1 objeto. Portanto Abstract Factory (Fábrica Abstrata)

CRIA 1 OBJETO CRIA 1 FAMÍLIA DE OBJETO

designpatterns.com.br 28
Abstract Factory
<<interface>>

TrajeFactory Abstract Factory RoupaTronco

criarRoupaTronco(): RoupaTronco
TrajeFactory é a Abstract Factory.

criarRoupaPernas(): RoupaPernas TrajeFactoryFormal e TrajeFactoryCasual são classes Factories Concretas que


implementam TrajeFactory. Cada Factory Concreta cria uma família de objetos. Camisa Camiseta

criarRoupaPes(): RoupaPes

<<interface>>
RoupaPernas
TrajeFactoryFormal TrajeFactoryCasual

criarRoupaTronco(): Camisa criarRoupaTronco(): Camiseta

criarRoupaPernas(): Calcas criarRoupaPernas(): Bermuda


Calcas Bermuda
criarRoupaPes(): Sapatos criarRoupaPes(): Tenis

<<interface>>
RoupaPes

TrajeFactoryFormal
TrajeFactoryCasual cria
cria uma família que
uma família que contém
contém os objetos
os objetos das classes
das classes Camisa, Sapatos Tenis
Camiseta, Bermuma e
Calcas e Sapatos.
Tenis.

designpatterns.com.br 29
Abstract Factory
A escolha da fábrica abstrata determina quais objetos serão criados.

Manequim this.tronco = factory.criarRoupaTronco();


this.pernas = factory.criarRoupaPenas();
tronco: RoupaTronco this.tronco = factory.criarRoupaPes();
pernas: RoupaPernas
pes: RoupaPes

construtor(TrajeFactory factory)

tff = new TrajeFactoryFormal(); tfc = new TrajeFactoryCasual();

manequim = new Manequim(tff); manequim = new Manequim(tfc);

TrajeFactory

criarRoupaTronco(): RoupaTronco
Abstract Factory
Os métodos de criarRoupaPernas(): RoupaPernas Os métodos de
TrajeFactoryFormal TrajeFactoryCasual
criarRoupaPes(): RoupaPes
serão chamados no serão chamados no
contrutor da classe contrutor da classe
Manequim. Manequim.
Factories Concretas

TrajeFactoryFormal TrajeFactoryCasual
Se no futuro surgirem
criarRoupaTronco(): Camisa criarRoupaTronco(): Camiseta novos trajes, bastará
criar novas Factories
criarRoupaPernas(): Calcas criarRoupaPernas(): Bermuda contretas.
criarRoupaPes(): Sapatos criarRoupaPes(): Tenis

designpatterns.com.br 30
Abstract Factory DIAGRAMA DE CLASSES
ILUSTRADO

<<interface>>
RoupaTronco

Cliente Manequim

tronco: RoupaTronco
criarManequimFormal(): Manequim pernas: RoupaPernas
pes: RoupaPes Camiseta
Camisa
criarManequimCasual(): Manequim
construtor(TrajeFactory factory)

tff = new TrajeFactoryFormal();


manequim = new Manequim(tff); TrajeFactory
<<interface>>
RoupaPernas
criarRoupaTronco(): RoupaTronco

tfc = new TrajeFactoryCasual(); criarRoupaPernas(): RoupaPernas Abstract Factory


manequim = new Manequim(tfc);
criarRoupaPes(): RoupaPes
Calcas Bermuda

TrajeFactoryFormal TrajeFactoryCasual

criarRoupaTronco(): Camisa criarRoupaTronco(): Camiseta


<<interface>>
RoupaPes
criarRoupaPernas(): Calcas criarRoupaPernas(): Bermuda

criarRoupaPes(): Sapatos criarRoupaPes(): Tenis

Factory Concreta Factory Concreta


Sapatos Tenis

designpatterns.com.br 31
MÓDULO 05
PADRÃO ESTRUTURAL

Facade POO

"O meu papel é implicar


as coisas "

designpatterns.com.br 32
Facade
A DEFINIÇÃO
O padrão Facade fornece uma interface unificada para um conjunto de
interfaces em um subsistema. O Facade define uma interface de nível
mais alto que facilita a utilização do subsistema.

Cabeça O EXEMPLO POO


Deseja-se fornecer uma interface simplificada para a montagem
Braço Braço de um robô composto por muitas partes.
Esquerdo Direito

Tronco

Perna Perna
Esquerda Direita

designpatterns.com.br 33
Facade
O Cliente precisa de um Robô.

Para montar um robô o cliente precisa conhecer Cliente Tronco criar


cada classe que faz parte do subsistema que cria um Cabeca criar
robô. montarRobo BracoEsquerdo criar
BracoDireito criar
O Cliente precisa conhecer toda a complexidade do
Cliente depende PernaEsquerda criar
processo de montagem de um robô.
de 6 classes criar
PernaDireita

Cabeca

criar
Cliente2 BracoEsquerdo

criar
BracoDireito
ClienteN
Tronco
criar
O Cliente 2 ainda não precisa
de um robô. Porém, se ele vir a criar montarRobo
precisar, também terá que
conhecer todas as classes e Qualquer cliente que vier a
processos envolvido na precisar de um Robô terá que
montagem de um robô. PernaEsquerda PernaDireita conhecer todo esse processo.

criar criar

designpatterns.com.br 34
Facade DIAGRAMA DE CLASSES
ILUSTRADO
1
A classe Facade externaliza todo o subsistema
Cliente Cliente2
... ClienteN
robô de uma forma simplificada.

Ela fornece uma fachada simplificada para algo

2 2 Não importa quantos clientes precisam de um robô,


que é complexo.
2 eles podem sempre recorrer à classe Facade.
1 Graças à classe Facade os clientes não
Facade precisam mais se preocupar com o processo de
montagem de um robô.
Tronco criar
montarRobo
Cabeca criar
BracoEsquerdo
BracoDireito
criar
criar
2
PernaEsquerda criar Os clientes dependem apenas da classe Facade.
PernaDireita criar

E não mais das 6 classes como antes da classe


Cabeca
Esse é o Facade Existir.
BracoEsquerdo
criar subsistema de

criar
robô. 3
BracoDireito Embora a classe Facade simplifique o acesso, as
Tudo o que é
criar classes do subsistema continuam acessíveis. O
Tronco refente a robô
Facade é uma alternativa simplificada.
fica aqui dentro.
criar
Veja por exemplo que a classe ClienteEspecifico
precisa apenas das pernas do robô. Ela pode
Um subsistema pode possuir mais de acessar as classes diretamente, sem a
PernaEsquerda PernaDireita
uma classe de fachada (Facade) intermediação da classe Facade.
criar criar

Para manter a explicação simples, a classe Facade do exemplo possui apenas um método
que engloba todas as classes do subsistema.

ClienteEspecífico É importante dizer que a classe Facade pode possuir quantos métodos forem necessários.
Cada método pode simplificar o acesso a algumas classes apenas, não necessariamente a
3 todas as classes do subsistemas.

designpatterns.com.br 35
MÓDULO 06
PADRÃO COMPORTAMENTAL

Template Method POO

"Faça o que quiser desde


que sigam o que eu defini"

designpatterns.com.br 36
Template Method
A DEFINIÇÃO
O padrão Template Method define o esqueleto de um algoritmo dentro
de um método, transferindo alguns de seus passos para subclasses. O
Template Method permite que as subclasses redefinam certos passos
de um algoritmo sem alterar a estrutura do mesmo.

POO
O EXEMPLO
Pão
Deseja-se garantir que os ingredientes dos hambúrgueres sejam
Acompanhamento montados sempre na mesma ordem, porém os ingrediente
Queijo podem variar.
Hamburguer
Salada

designpatterns.com.br 37
Template Method DIAGRAMA DE CLASSES
ILUSTRADO

Vamos assumir que:


1 3 1
Os métodos Hamburguer
Possuem
pao, acompanhamento e salada O Template Method garante que
pao implementação
a receita será seguida.
acompanhamento Padrão
queijo
Primeiro vai o pão, dentro dele
vai o acompanhamento depois o
hambuguer 2
Possuem uma implementação salada São métodos
queijo, hambúrguer e por fim a
padrão. Deste modo, as Abstratos
salada.
subclasses de Hamburguer
podem optar por utilizar o 3
método padrão fornecido pela Template
superclasse OU sobreescrever Method
os métodos para impor suas
próprias particularidades. ça
He
ran
ran ça
He
Herança
4 5 6
HamburguerVegetariano HamburguerCarne HamburguerFrango
2
Os métodos
queijo e hamburguer

São abstratos. Isso permite que


o Template Method possa Implementa Implementa Implementa
invocar métodos cujas
4 5 6
implementações ainda nem
existem. Utiliza o padrão Utiliza o padrão Utiliza o padrão

Tais implementações serão Sobreescreve


concretizadas nas subclasses de Sobreescreve
Hamburguer.

designpatterns.com.br 38
MÓDULO 07
PADRÃO ESTRUTURAL

Adapter
POO

"Eu faço classes que não são


compatíveis trabalharem justas"

designpatterns.com.br 39
Adapter
A DEFINIÇÃO
Converter uma interface de uma classe (incompatível) para outra
interface que o cliente espera encontrar. O Adapter busca permitir que
classes com interfaces incompatíveis trabalhem juntas.

POO
O EXEMPLO
Para ter uma conexão mais rápida deseja-se ligar um cabo
Ethernet em um notebook que possui apenas portas USB.

designpatterns.com.br 40
Adapter
Toda a complexidade do O adaptador converte uma interface
processo de adaptação fica incompatível em compatível
dentro do adaptador (Adapter)

Temos uma interface Ethernet


que é incompatível com o que o
notebook espera

O notebook espera uma interface USB

designpatterns.com.br 41
Adapter DIAGRAMA DE CLASSES
ILUSTRADO

1 5
Essa é nossa interface ALVO. O Aqui acontece o processo de
CLIENTE espera receber uma ADAPTAÇÃO. Cada método do ADAPTER
interface que tenha 1 método
laranja, 1 vermelho e outro verde.
chama seu equivalente na classe
ADAPTADA, recupera o retorno e o
6
fornece ao CLIENTE seguindo as
restrições impostas pela interface ALVO.

Repare que o método verde é identico na O cliente consumidor do


classe ADAPTADA, ele não precisa de
padrão de projeto é Nossa interface alvo é
adaptação
equivalente ao notebook equivalente a porta USB
2 4 Alvo
1
6 Cliente
A classe que temos não possui os
métodos esperados pelo cliente.
As cores não batem.
É comum existir cenários onde 1
método do ADAPER é equivalente a N
5
métodos da classe ADAPTADA e vice-
versa.

3
A classe ADAPTER implementa a
interface alvo, logo, ela deve ter os
métodos (cores) que a interface
Alvo define.
3 2
Adapter Adaptada

4
O CLIENTE aceita objetos de
qualquer classe que implemente a
interface alvo. Ele sabe que a
interface alvo garante os métodos
nas cores que ele precisa.
Esse é nosso adaptador A classe adaptada é
Os métodos estão sendo equivalente ao cabo Ethernet
representados por cores (Classe incompatível)

designpatterns.com.br 42
MÓDULO 08
PADRÃO COMPORTAMENTAL

State POO

"Tudo depende do estado


em que eu estou"

designpatterns.com.br 43
State
A DEFINIÇÃO
O padrão de projeto State permite que um objeto altere o seu
comportamento quando o seu estado interno muda. O objeto parecerá
ter mudado de classe.

POO
O EXEMPLO
Gerenciar as interações do usuário com um Smartphone de
acordo com seus possíveis estados.

designpatterns.com.br 44
State
Considere que o Smartphone pode estar nos seguintes estados:

Bloqueado: A única interação possível é digitar a senha.

Travado: O Smartphone fica nesse estado após o usuário errar a senha 3


vezes.

Nenhuma interação com o smartphone é possível nesse estado.

O usuário precisa aguadar 10 segundo para que o celular volte para o


estado Bloqueado.

Desbloqueado: O usuário pode realizar todas as interações possíveis.

designpatterns.com.br 45
State
Vamos utilizar uma Máquina de Estados para ilustrar o comportamento do Smarthpone

As Transições podem levar o


sistema (Smartphone) de um
Quando o usuário digita O usuário digitou a estado para outro.
uma senha errada, o senha correta. O
Smartphone continua no Smartphone vai para o
estado Bloqueado. estado Desbloqueado. TRANSIÇÕES
Senha não
Validada
ESTADOS
Aqui o usuário pode
apenas digitar a Senha
senha. Validada
Nesse estado o
usuário pode utilizar
Bloqueado Desbloqueado todos os recursos
do Smartphone.
Quando o usuário Bloquear
erra a senha por 3
vezes consecutivas o Travar
Smartphone vai para O usuário apertou o
o estado Travado.
Destravar
botão de bloqueio
do Smartphone. Ele
volta para o estado
Bloqueado.
Travado 10 segundos se
passaram desde o
Aqui a única coisa
que o usuário pode travamento. O
fazer é aguardar os Smartphone volta ao
10 segundos. estado Bloqueado.

designpatterns.com.br 46
State
O padrão State sugere que cada estado se torne um objeto de estado. Para existir um
Senha não
objeto é preciso que exista uma classe.
Validada
Bloqueado Desbloqueado Travado
Senha
Validada

Bloqueado Desbloqueado
Bloquear

Travar
Destravar
O padrão também sugere que cada transição se torne um Método dos objetos de estado.

Travado Bloqueado Desbloqueado Travado

senhaValidada() senhaValidada() senhaValidada()

senhaNaoValidada() senhaNaoValidada() senhaNaoValidada()

bloquear() bloquear() bloquear()

travar() travar() travar()

destravar() destravar() destravar()

designpatterns.com.br 47
State
Senha não
Validada

Senha
Validada Além disso, todos os objetos de estado devem <<interface>>
ser exergados da mesma forma pelo sistema. State
Bloqueado Desbloqueado
Eles precisam ter um tipo em comum. Todos
Bloquear senhaValidada()
precisam implementar uma mesma interface.
Travar senhaNaoValidada()
Destravar
bloquear()

travar()

Travado
destravar()

Cada uma das classes de estado trata as transições da forma


que lhe convêm.

Por exemplo, no método senhaNaoValidada da classe Bloqueado


pode existir um contador que ao atingir o valor 3 chama o método
Bloqueado Desbloqueado Travado
travar.
senhaValidada() senhaValidada() senhaValidada()

No método travar pode existir um timer que após 10 segundos senhaNaoValidada() senhaNaoValidada() senhaNaoValidada()

chama o método destravar. bloquear() bloquear() bloquear()

travar() travar() travar()

Por outro lado, as funcionalidades descritas acima não fazem destravar() destravar() destravar()

sentido para a classe Desbloqueado, já que não é possível errar a


senha ou travar o Smartphone no estado Desbloqueado.
Todas essas classes são do tipo State

designpatterns.com.br 48
State
Senha não
<<interface>> Validada
State
Senha
senhaValidada()
Validada
senhaNaoValidada()
Bloqueado Desbloqueado
bloquear()
Bloquear
travar()
Travar
destravar() Destravar

Travado

Bloqueado Desbloqueado Travado


Vai para o estado
Desbloquado
senhaValidada() senhaValidada()
Lança erro senhaValidada() Lança Erro
Continua no estado
senhaNaoValidada() senhaNaoValidada() senhaNaoValidada()
Bloqueado
bloquear() bloquear() bloquear()
Lança erro
travar() travar() Vai para o estado travar() Vai para o estado
Vai para o estado Bloqueado Bloqueado
destravar() Travado destravar() destravar()

Quando existe transição a partir de um determinado estado, o método da transição possui implementação.

Quando não exite transição a partir de um determinado estado, o método da transição lança um erro.

Por exemplo: A partir do estado Desbloqueado não existe nenhuma transição Senha Validada, logo, o método senhaValidada da classe
Desbloqueado lança um erro.

designpatterns.com.br 49
State DIAGRAMA DE CLASSES
ILUSTRADO
Objeto de
O objeto de contexto é o contexto
objeto que troca de estado. <<interface>>
Smartphone State Para que os objetos de
No nosso caso a instância
estado possam trocar o
da classe Smartphone. bloqueadoState: State
desbloqueadoState: State
senhaValidada() estado atual do
travado: State senhaNaoValidada() Smartphone (objeto de
estadoAtual: State contexto) eles precisam
bloquear()
conhecer o Smartphone.
this.estadoAtual.senhaValidada(); contrutor() travar() Portanto, os objetos de
senhaValidada() destravar()
estado devem receber o
objeto Smartphone em
this.estadoAtual.senhaNaoValidada(); senhaNaoValidada()
seu construtor.
bloquear()

this.estadoAtual.bloquear(); travar()

destravar()

this.estadoAtual.travar(); setEstadoAtual(State estado)

this.estadoAtual.destravar(); Bloqueado Desbloqueado Travado

smartphone: Smartphone smartphone: Smartphone smartphone: Smartphone


this.estadoAtual = estado;
contrutor(Smartphone smartphone) contrutor(Smartphone smartphone) contrutor(Smartphone smartphone)

senhaValidada() senhaValidada() senhaValidada()

this.bloqueadoState = new Bloqueado(this); senhaNaoValidada() senhaNaoValidada() senhaNaoValidada()

this.desbloqueadoState = new Desbloqueado(this); bloquear() bloquear() bloquear()


this.travadoState = new Travado(this);
travar() travar() travar()

this.estadoAtual = this.bloqueadoState(); destravar() destravar() destravar()

O estado inicial do objeto Smartphone Todos os objetos de estado são inicializados recebendo o
fica definido como sendo Bloqueado. próprio objeto Smatphone como parâmetro.

designpatterns.com.br 50
State DIAGRAMA DE CLASSES
ILUSTRADO - CONTINUAÇÃO
Travado
Smartphone <<interface>>
State smartphone: Smartphone

contrutor(Smartphone smartphone) this.smartphone = smartphone;


senhaValidada()

senhaNaoValidada()

bloquear()

//Imprime um erro ou lança exception travar()


//Troca o estado para Destravado;
destravar() if (se passaram 10 segundos) { //Pseudocódigo
Esse é o mesmo diagrama de classes que this.smartphone.setEstadoAtual(this.smartphone.destravadoState);
o da página anterior. }

Desbloqueado
Alguns detalhes da classe Smartphone e
da interface State foram ocultados para smartphone: Smartphone

otimizar o espaço na página.


contrutor(Smartphone smartphone) this.smartphone = smartphone;
senhaValidada()

senhaNaoValidada()

//Troca o estado para Bloqueado;


bloquear()
this.smartphone.setEstadoAtual(this.smartphone.bloquadoEstate);
//Imprime um erro ou lança exception travar()

destravar()

De zoom na página para ver as Seria mais adequado que


a classe Smartphone
informações em um tamanho maior. tivesse getters para os
estados. Mas vamos
Bloqueado manter as coisas simples
this.smartphone = smartphone; por aqui.
smartphone: Smartphone
Senha não
Validada
contrutor(Smartphone smartphone) //Troca o estado para Desbloqueado;
this.smartphone.setEstadoAtual(this.smartphone.desbloqueadoState);
senhaValidada() Senha
Validada
senhaNaoValidada()
if (errou a senha 3 vezes) { //Pseudocódigo Bloqueado Desbloqueado
bloquear() this.travar(); //chama o método travar Bloquear

//Imprime um erro ou lança exception travar()


}
Travar
//Se não entrar no if não troca de estado Destravar
destravar()

//Troca o estado do Smartphone para travado; Travado


this.smartphone.setEstadoAtual(this.smartphone.travadoState);

designpatterns.com.br 51
MÓDULO 09
PADRÃO COMPORTAMENTAL

Observer POO

"Se algo mudar pode


deixar que eu aviso"

designpatterns.com.br 52
Observer
A DEFINIÇÃO
O Observer é um padrão de projeto de software que define uma
dependência um-para-muitos entre objetos, de modo que quando um
objeto muda seu estado, todos os seus dependentes são notificados e
atualizados automaticamente.

POO
O EXEMPLO
Manter objetos leitores atualizados sobre as noticias que outro
objeto jornalista publica.

designpatterns.com.br 53
Observer
O problema da abordagem ao lado é a
sobrecarga de solicitações Esse objeto não
deseja receber as
desnecessárias ao objeto Jornalista. Esse objetos Leitores
novidades
desejam se manter
Por exemplo, suponha que uma nova atualizados das ultimas
notícia levou 60 segundo para ser notícias.
a 10s de?
publicada. Nesse tempo cada objeto A cad a novida
Objeto Leitor A
Leitor fez 6 solicitações para o objeto algum A cada 10 segundos eles
Tem
Jornalista. Somente a ultima solicitação A cada 10s
ade? perguntam para o objeto
retornou uma notícia, portanto, cada Tem alguma novid
A ca
jornalista se alguma noticia
objeto fez 5 solicitações desnecessárias. Tem algumda 10s
a novidade? foi lançada.
Objeto Leitor B
Tem
Outro ponto, é a quantidade de objetos alguA cada 10 Eles devem saber para
Objeto Jornalista ma n s
ovid
Leitores. Quanto mais Leitores existirem, ade? quem perguntar sobre
maior será a quantidade de solicitações Objeto Leitor C novas notícias. Portanto, o
desnecessárias. objeto Jornalista deve ser
conhecido pelos objetos
Por exemplo, em 60 segundo cada objeto Leitores.
Objeto Leitor D
faz 6 solicitações. logo: Esse objeto não
4 objetos Leitores fazem 24 deseja receber as
solicitações. novidades
10 objetos leitores fazem 60
solicitações.
Aqui, muitos objetos dependem de 1 único objeto. Muitos Leitores dependem de apenas
1 Jornalista. (Dependencia muitos-para-um)

designpatterns.com.br 54
Observer
O padrão de projeto observer propõe que os objetos observadores possam pedir ao objeto de interesse que os notifiquem sempre que ele sofrear alguma atualização.

Para tornar essa abordagem possível é preciso que exista um acordo entre o Subject (Jornalista) e Observers (Leitores):

Observers:
Precisam fornecer um canal para que o Subject os notifiquem.
Precisam conhecer o Subject que desejam observar.

Subject:
Esse objeto não
Precisa fornecer um canal para que os observers possam se cadastrar como observadores. deseja receber as
E também um canal para que os Observers possam se descadastrar como observadores. novidades
Deve ser capaz de notificar todos os observers quando sofrer uma atualização (nova noticia).

Objetos Observadores
(Observers)
Graças ao padrão Observer, agora não existe mais LeitorTipo1
o problema de solicitações desnecessárias

de
ovida
Objeto que gera o assunto de interesse nho n Objeto Leitor A
ora eu te
(Subject) ag
Hey, Os objetos Leitores
o novidade
Hey, agora eu tenh (Observers) podem ser
Hey, agora eu instâncias de classes
tenho novidad Objeto Leitor B
e diferentes
Hey,
agora
eu te
Objeto Leitor A Objeto Jornalista nho LeitorTipo2
novid
Objeto Leitor B ade
Objeto Leitor C
Objeto Leitor C
Objeto Leitor D
Sempre que uma nova
Lista de objetos notícia é lançada o
que pediram para Jornalista notifica Objeto Leitor D
serem notificados todos os leitores que se
inscreveram

Aqui, 1 objeto Jornalista depende de muitos objetos leitores. Esse objeto não
(Dependencia um-para-muitos) deseja receber as
novidades

designpatterns.com.br 55
Observer
O padrão de projeto observer propõe que os objetos observadores possam pedir ao objeto de interesse que os notifiquem sempre que ele sofrear alguma atualização.

Para tornar essa abordagem possível é preciso que exista um acordo entre o Subject (Jornalista) e Observers (Leitores):

Observers:

Precisam fornecer um canal para que o Subject os notifiquem. 1


Precisam conhecer o Subject que desejam observar. 2
Subject:
Veja onde cada um desses
Precisa fornecer um canal para que os observers possam se cadastrar como 3 pontos se encaixam no
observadores. diagrama de classes
E também um canal para que os Observers possam se descadastrar como 4
observadores.

Ser capaz de notificar todos os observers quando sofrer uma atualização. 5 <<interface>> <<interface>>
Subject Observer

3 senhaValidada() observer)
inscrever(Observer senhaValidada() noticia)
receberNoticia(string 1
senhaValidada() observer)
desinscrever(Observer 4
5 notificar()

LeitorTipo1 LeitorTipo2
Jornalista
2 jornalista: Jornalista | null 2 jornalista: Jornalista | null

listaObservers: array
receberNoticia(string noticia) receberNoticia(string noticia)
inscrever(Observer observer)

senhaValidada() observer)
desinscrever(Observer

notificar()

designpatterns.com.br 56
Observer
Um pouco de código para exemplificar
/*
Adiciona o observer recebido por parâmetro ao array (ou
<<interface>> <<interface>>
outra estrutura de dados) listaObservers.
Subject Observer
Aqui você pode adicionar manualmente ou utilizar um senhaValidada() observer)
inscrever(Observer senhaValidada() noticia)
receberNoticia(string
método add(), push(), append() ou qualquer outro método
fornecido pela sua linguagem de programação favorita. senhaValidada() observer)
desinscrever(Observer

O importante é adicionar o objeto observer a "lista" de notificar()


objetos a serem notificados.
*/
LeitorTipo1 LeitorTipo2
NOTA: Aqui eu defini listaObservers como sendo do tipo array por se
tratar de uma estrutura de dadas mais genérica. Arrays ou Vetores são Jornalista jornalista: Jornalista| null jornalista: Jornalista| null
popularmente conhecidos. Saiba que aqui você pode, e deve, utilizar a
estrutura de dados que achar mais apropriada ao seu problema. listaObservers: array
receberNoticia(string noticia) receberNoticia(string noticia)
inscrever(Observer observer)

/* senhaValidada() observer)
desinscrever(Observer
Remove o observer recebido por parâmetro do array (ou
outra estrutura de dados) listaObservers. notificar()

Aqui você pode remover manualmente ou utilizar um //Recebe a noticia e faz algo com ela (manipula ou armazena)
método remove() ou qualquer outro método fornecido pela
sua linguagem de programação favorita. Os padrões de projeto são proposta de desing de código. //O Jornalista pode se passado no construtor do observador
Raramente você seguira a implementação pura do padrão. public function construtor (Jonalista jornalista) {
O importante é remover o objeto observer a "lista" de this.jornalista = jornalista;
objetos a serem notificados. this.jornalista.inscrever(this);
É comum que existam diversas variações e adequações do
*/ }
código do padrão, porém, mantendo a ideia central que o
padrão dita.
//Para um maior nível de abstração
para cada objeto observer contido na listaObservers () { //Também, é possível esperar o super tipo Subject no construtor
/*Em algum lugar de seu código o objeto produz uma
Veja ao lado algumas formas diferentes de implementar o
//Nesse caso, o tipo do atributo no diagrama deveria ser trocado para "Subject | null"
noticia (string) e a envia para todos os observadores
processo de atribuição de um objeto Jornalista ao atributo public function construtor (Subject jornalista) {
que se inscreverem em sua lista.*/ jornalista dos Leitores (1 e 2). this.jornalista = jornalista;
chamar o método receberNoticia(noticia); this.jornalista.inscrever(this);
} Também repare no processo de inscrição dos Leitores }
(observers) em um objeto Jornalista.
//Um pouco mais baixo nível //Talvez seja interessante ter um método para gerenciar a observação de um Subject
foreach (listaObserver as observer) { public function observar (Subject jornalista) {
observer.receberNoticia(noticia); this.jornalista = jornalista;
} this.jornalista.inscrever(this);
}

designpatterns.com.br 57
MÓDULO 10
PADRÃO COMPORTAMENTAL

Visitor
"Eu visito classes para
deixá-las mais poderosas"
designpatterns.com.br 58
Visitor UM PRESENTE
PRA VOCÊ
Rabiscando
PADRÕES DE
PROJETO
AULA COMPLETA EM VÍDEO

E
APERT
Y
O PLA
VISITOR

APROFUNDE SEUS CONHECIMENTOS SOBRE O PADRÃO DE


PROJETO VISITOR COM ESSA AULA COMPLETA E GRATUITA

designpatterns.com.br 59
Rabiscando
PADRÕES DE
PROJETO O SEU PRÓXIMO PASSO
O Rabiscando Padrões de Projeto é um
treinamento completo com tudo o que você
precisa para aplicar todos os 23 Design
Patterns clássicos da GoF em seus projetos.

O treinamento que vai te levar para o


próximo nível como desenvolvedor(a) de
sofware.

SAIBA MAIS
Cliq u e a q ui

designpatterns.com.br 60
Deixe a sua avaliação
PODE POR POR FAVOR ME DIZER O QUE ACHO DO EBOOK?

POO

CLIQUE AQUI
PARA AVALIAR

Sua opinião é muito importante!

designpatterns.com.br 61
Agradecimentos
Deixo aqui meu muito obrigado a todos os alunos do treinamento Rabiscando Padrões de
Projeto.

Graças a eles eu pude me dar ao luxo de reservar horas do meu trabalho para criar esse e-book
gratuito.

Também te agradeço querido leitor. Obrigado pelo seu download. Em uma época onde existe
POO
uma grande escassez de BONS profissionais no mercado, é sempre gratificante notar a busca
por entender os conceitos por trás do código.

Saber como resolver problemas é uma das maiores virtudes de nós desenvolvedores.

Linguagens e frameworks da moda vem e vão, mas os conceitos são sólidos. É que ai que estão
os Design Patterns.

designpatterns.com.br 62
Recomendações e Referências
Esses são alguns dos livros que de alguma forma influenciaram a produção deste e-book.

POO

Clique nos livros para saber mais

designpatterns.com.br 63
Reflexão Final
Certa vez ouvi uma frase que me marcou. Infelizmente não lembro o nome do autor para dar os
créditos. Era algo assim:

A cada commit, a cada deploy,


surgem novos códigos para dar
manutenção.
POO
Pelo bem do seu eu do futuro,
Pelo bem da sua equipe

escreva bons códigos.

Até a próxima!
designpatterns.com.br 64

Você também pode gostar