Você está na página 1de 62

Rabiscando

PADRÕES DE
PROJETO

O guia

Ilustrado

POO
ANTES DE QUALQUER COISA

RESPONDA O QUIZ INICIAL

CLIQUE AQUI
PARA RESPONDER

Não se preocupe se você não sabe muita coisa sobre Design Patterns. O objetivo
deste quiz é justamente medir seus conhecimentos antes que você faça a leitura
deste e-book.

No final do e-book existe outro quiz como este. Se você se dedicar de verdade a
leitura deste e-book o resultado do quiz final com certeza será melhor que o
resultado do quiz inicial.

padroesdeprojeto.com.br Página 2
Olá,

Meu nome é Vinicius Vivan, sou cientista


da computação e criador desse e-book.

POO
Esse material é resultado da minha
experiência como desenvolvedor e também
de muito estudo e planejamento, para que
eu pudesse entregar a você, de forma
gratuita, um conteúdo extremamente
didático.

Meu objetivo aqui é acelerar o seu processo


de aprendizado dos Design Patterns.
Acredite, eles são um ingrediente
fundamental para um código de qualidade!

padroesdeprojeto.com.br Página 3
Porque ESTUDAR
Design Patterns?
Eu não destaquei a palavra ESTUDAR em vão!

VOCÊ GOSTA DE TER TEMPO LIVRE? POO


Ter momentos de qualidade com a sua família.

Jogar videogame.

Assistir filmes e seriados.

Ter uma boa qualidade de sono.

Sair com os amigos.

Parar de trabalhar na hora certa.

Então por isso você precisa ESTUDAR Design Patterns!


padroesdeprojeto.com.br Página 4
Porque ESTUDAR
Design Patterns?
Você tem um comportamento Pró-ativo ou Reativo?
POO
Você domina os Design Patterns e está pronto(a) para aplicá-los
sempre você percebe uma oportunidade.

Você Aplica os Design Patterns para evitar problemas futuros.


Principalmente quanto se trata de mudanças ou expansão de código.

Você aplica os Design Patterns quando ALGUÉM te fala que dá pra


aplicar. Você estuda conforme a demanda.

Você tenta aplicar os Design Patterns quando está reescrevendo um


código do zero porque já perdeu o controle sobre ele.

padroesdeprojeto.com.br Página 5
Porque ESTUDAR
Design Patterns?
Dominar os Design Patterns é um dos fatores que
separam DEVs Júnior dos Plenos/Sênior.POO
Ao DOMINAR os Design Patterns, com certeza você já terá um grande conhecimento sobre
programação orientada a objetos.

Eu não me refiro a linguagens de programação ou Frameworks, mas sim aos conceitos.

Você terá muita consciência e cuidado com o nível de acoplamento do seu código, se ele
será fácil de ler, manter ou expandir.

Você já saberá exatamente quando é mais adequado utilizar uma classe abstrada, uma
interface ou então quando optar pela composição ao invés da herança.

padroesdeprojeto.com.br Página 6
Porque ESTUDAR
Design Patterns?
Ao dominar os Design Patterns
você estará em outro nível. POO
Pra você não bastará resolver o problema, pra você, o problema deverá ser resolvido
com excelência.

Veja bem, eu não estou te dizendo que você nunca mais fará uma gambiarra ou outra.
Eu também sou desenvolvedor e sei que as vezes os prazos são curtos e não dá pra
fazer tudo de forma perfeita.

Porém, você fará o melhor que você pode nas condições que você tiver!

Você não deixará de fazer o melhor por falta de conhecimento, mas sim, por uma
decisão consciente totalmente sua. Você terá segurança suficiente sobre seu código a
ponto de saber que a qualquer momento você poderá voltar ali e fazer melhor.

padroesdeprojeto.com.br Página 7
Porque ESTUDAR
Design Patterns?
Ou seja,

Você precisa estudar Design Patterns para não "surtar" quando tiver que dar
manutenção em um código que você mesmo escreveu.

Você precisa estudar Design Patterns para que outros desenvolvedores não "surtem"
ao ter que dar manutenção em um código que você escreveu.

Eu te garanto, por experiência própria, que as Te darão muitas horas "livres" no futuro para
horas "ocupadas" que você gastará estudando que você possa fazer aquilo que mais gosta.
Design Pattterns.

padroesdeprojeto.com.br Página 8
Agradecimentos

Deixo aqui meu muito obrigado a todos os alunos do treinamento


Rabiscando Padrões de Projeto.

POO
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 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.

padroesdeprojeto.com.br Página 9
"The only way to go fast is to go well"
POO

"A única forma de ir rápido é ir certo"

Robert Cecil Martin


(Uncle Bob)

padroesdeprojeto.com.br Página 10
Atenção!
Antes de avançar nesse e-book eu preciso que você saiba de algumas coisas.
POO
Esse material é para desenvolvedores que possuem alguma experiência com
programação orientada a objetos.

Para garantir que a maioria dos leitores tenham o conhecimento básico


necessário, eu disponibilizei o módulo 00 que é um NIVELAMENTO de
conhecimentos.

Nele você encontrará duas aulas em vídeo que eu extrai do treinamento


Rabiscando Padrões de Projeto.

padroesdeprojeto.com.br Página 11
Nivelamento
Para entender melhor o conteúdo
deste e-book é precisoPOO
compreender
alguns conceitos básicos sobre
padrões de projeto, digrama de
classes e orientação a objetos

00 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Nivelamento Página 12
AULAS DE NIVELAMENTO EM VÍDEO

NESSA AULA VOCÊ APRENDERÁ NESSA AULA VOCÊ APRENDERÁ


As definições de classe, classe abstrata, métodos, O que são padrões de projeto.
métodos abstratos, objetos e interfaces.
O que e quais são os padrões criacionais.
O que é um diagrama de classes e alguns dos
relacionamentos entre classes (Associação, O que e quais são os padrões Estruturais.
Generalização, Realização, Agregação e Composição).
O que e quais são os padrões comportamentais.
Os pilares da orientação a objetos (Encapsulamento,
Herança, Abstração e Polimorfismo).

Rabiscando Rabiscando
PADRÕES DE PADRÕES DE
PROJETO APERT
E PROJETO
Y
O PLA

REVISÃO DE CONCEITOS O QUE SÃO PADRÕES DE PROJETO?

APROFUNDE SEUS CONHECIMENTOS SOBRE PADRÕES DE


PROJETO, DIAGRAMA DE CLASSES E ORIENTAÇÃO A OBJETOS!
padroesdeprojeto.com.br Nivelamento Página 13
Visitor
Padrão Comportamental

POO

01 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Visitor Página 14
UM PRESENTE Rabiscando
PADRÕES DE
PRA VOCÊ PROJETO
AULA COMPLETA EM VÍDEO

E
VISITOR APERT
Y
O PLA

BÔNUS
MANUAL DE USO
COMPLETO EM PDF

APROFUNDE SEUS CONHECIMENTOS SOBRE O PADRÃO DE


PROJETO VISITOR COM ESSA AULA COMPLETA E GRATUITA

padroesdeprojeto.com.br Visitor Página 15


Singleton
Padrão Criacional
POO

02 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Singleton Página 16
SINGLETON
Padrão Criacional

PROBLEMA: Deseja-se criar


DEFINIÇÃO: O padrão Singleton garante que uma classe tenha uma única instância de um
apenas uma instância e fornece um ponto global de acesso a ela. objeto de conexão com o
banco de dados.

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.

padroesdeprojeto.com.br Singleton Página 17


DIAGRAMA DE CLASSES ILUSTRADO

1
Talvez você esteja se perguntando o motivo ClienteA Conexao
do Singleton estar nesse e-book, já que ele é
considerado um anti-pattern. Os motivos con: Conexao
instancia: Conexao | null 2
são muito simples:

1) Existe um conceito muito interessante por


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

padroesdeprojeto.com.br Singleton Página 18


Strategy
Padrão Comportamental
POO

03 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Strategy Página 19
STRATEGY
Padrão Comportamental

DEFINIÇÃO: O padrão de projeto Strategy define uma família de PROBLEMA: Deseja-se criar
algoritmos, encapsula cada um deles e os torna intercambiáveis. uma calculadora de inteiros
O Strategy permite que o algoritmo varie independentemente dos que possa ter as operações
clientes que o utilizam. facilmente expandidas.

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.

* /

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

calcular(operandoA, operandoB)

padroesdeprojeto.com.br Strategy Página 20


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
setOperacao(Operacao operacao)
Soma Subtracao Multiplicacao Divisao

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); return operandoA * OperandoB

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

A classe calculadora possui os atributos s->calcular(operandoA, OperandoB)


4
São a implementações concretas das estratégias. No
operandoA, operandoB e operacao. Estaremos chamando o método
nosso contexto cada classe implementa uma operação
calcular da classe Soma.
diferente. Ao trocar a classe (operação), trocamos o
return operandoA + OperandoB comportamento.

padroesdeprojeto.com.br Strategy Página 21


Factory Method
Padrão Criacional

POO

04 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Factory Method Página 22
FACTORY METHOD
Padrão Comportamental

DEFINIÇÃO: O Padrão Factory Method define uma interface para PROBLEMA: Criar um
criar um objeto, mas permite que a subclasses possam decidir objeto manequim com uma
qual classe instanciar, possibilitando que uma classe seja capaz de peça de roupa.
prorrogar a instanciação de uma classe para subclasses.

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.

padroesdeprojeto.com.br Factory Method Página 23


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

criarRoupaFormal(string parteDoCorpo): Roupa


Camisa Camiseta

criarRoupaCasual(string parteDoCorpo): Roupa

switch (parteDoCorpo) { switch (parteDoCorpo) {


Exemplo de uma
case 'tronco': case 'tronco':
classe Cliente Calcas Bermuda
return new Camisa(); return new Camiseta();
utilizando a classe case 'pernas': case 'pernas':
Manequim. return new Calcas(); return new Bermuda();
case 'pes': case 'pes':
return new Sapatos(); return new Tenis();
} } Sapatos Tenis

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


formais. casuais.

Utilizando o método manequim = new Manequim(); Utilizando o método


manequim = new Manequim();
criarRoupaFormal criarRoupaCasual
roupa = manequim.criarRoupaFormal('tronco'); roupa = manequim.criarRoupaCasual('tronco');
/*supondo que Manequim possui um método setter*/ /*supondo que Manequim possui um método setter*/
manequim.setRoupa(roupa); manequim.setRoupa(roupa); Métodos diferentes
resultam em objetos
diferentes.
roupa = manequim.criarRoupaFormal('pernas'); roupa = manequim.criarRoupaCasual('pernas');
manequim.setRoupa(roupa); manequim.setRoupa(roupa);
Toda a lógica de criação
das roupas continua na
classe Manequim.

padroesdeprojeto.com.br Factory Method Página 24


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 de uma classe para subclasses.

Os dois métodos da classe Manequim foram


substituídos por um método abstrato.
Repare que o método CriarRoupa recebe o
por ter um método abstrato, Manequim se
mesmo parâmetro e possui o mesmo tipo de
torna uma classe abstrata.
criarRoupa é um método retorno que os métodos anteriores.
<<inteface>>
abstrado, então, as
subclases de Manequim
Manequim Roupa
deverão implementar esse
Dependência
método. roupa: Roupa
Esse método é a interface
Factory Method criarRoupa(string parteDoCorpo): Roupa para criar um objeto citada Camisa Camiseta
na definição.

Herança Herança

ManequimFormal ManequimCasual
Calcas Bermuda

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

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

padroesdeprojeto.com.br Factory Method Página 25


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

Camisa Camiseta
criarRoupa(string parteDoCorpo): Roupa Factory Method

Herança Herança

ManequimFormal ManequimCasual Calcas Bermuda

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

Sapatos Tenis

Exemplo de uma
classe Cliente
utilizando as Utilizando a subclasse
manequim = new ManequimFormal(); manequim = new ManequimCasual();
subclasses de ManequimCasual
Manequim. roupa = manequim.criarRoupa('tronco'); roupa = manequim.criarRoupa('tronco');
/*supondo que Manequim possui um método setter*/ /*supondo que Manequim possui um método setter*/
manequim.setRoupa(roupa); manequim.setRoupa(roupa);
Utilizando a
Subclasses diferentes
subclasse
resultam em objetos
ManequimFormal roupa = manequim.criarRoupa('pernas'); roupa = manequim.criarRoupa('pernas');
manequim.setRoupa(roupa); diferentes.
manequim.setRoupa(roupa);

Toda a lógica de criação


das roupas fica nas
subclasses (Factories).

padroesdeprojeto.com.br Factory Method Página


Página26
1
DIAGRAMA DE CLASSES ILUSTRADO
1 3 4
Cliente
A classe Manequim é uma classe Abstrata. É o tipo abstrato do objeto retornado pelo São as classes concretas que implementam
ela 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 Camisa
4 Camiseta

Herança Herança

2 2
ManequimFormal ManequimCasual

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


4 Bermuda

Dependência Concreta

4 Sapatos 4 Tenis
2
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

padroesdeprojeto.com.br Factory Method Página 27


Abstract Factory
Padrão Criacional

POO

05 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Abstract Factory Página 28
ABTRACT FACTORY
Padrão Comportamental

PROBLEMA: Criar um meio


DEFINIÇÃO: O padrão Abstract Factory fornece uma interface
para que um objeto
para criar famílias de objetos relacionados ou dependentes, sem
manequim possa ser vestido
especificar suas classes concretas.
com peças de roupas para o
tronco e pernas e sapatos.

Enquanto o padrão Factory Method fornece uma interface para a criação de objetos, o padrão Abstract As peças de roupas devem ser
Factory fornece uma interface para criar uma família de objetos.
coerentes com a ocasião. São
Em outras palavras, o Abstract Factory fornece uma interface para a criação de objetos que
elas: formal e casual. Além
fazem sentido juntos. Além disso, membros de uma família de objetos não devem se misturar disso o sistema deve ficar
com membros de outras famílias. aberto a novas ocasiões.
<<inteface>>
Roupa
Considere as mesmas classes de roupas que
utilizamos no padrão Factory Method.

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

Traje Formal Traje Casual

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

padroesdeprojeto.com.br Abstract Factory Página 29


Factory Method Abstract Factory

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

As Factories devem controlar os tipos de forma


Objetos de um único tipo explícita.

<<interface>> Familia Traje


Roupa
RoupaTronco RoupaPenas RoupaPes

Camisa Camiseta
Objetos de tipos diferentes

Camisa <<interface>> Camiseta


RoupaTronco

Calcas Bermuda

Calcas <<interface>> Bermuda


RoupaPernas

Sapatos Tenis

Sapatos <<interface>> Tenis


RoupaPes

padroesdeprojeto.com.br Abstract Factory Página 30


Factory Method Abstract Factory

Manequim Manequim <<interface>>


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

Aqui nós temos um método abstrato que


ManequimFactory <<interface>>
cria um objeto.
RoupaPes
factoryMethod(): Manequim Portanto Factory Method (Método Fabrica)

Aqui nós temos uma Classe abstrata


A intenção do Factory Method é encapsular o processo de TrajeFactory com métodos abstratos que
criação de 1 objeto. retornam tipos abstratos
criarRoupaTronco(): RoupaTronco
Cada um dos métodos é responsável
criarRoupaPernas(): RoupaPernas por criar um membro da família de
objetos (Família Traje)

criarRoupaPes(): RoupaPes Portanto Abstract Factory (Fábrica


CRIA 1 OBJETO Abstrata)

A intenção do Abstract Factory é encapsular o processo de


criação de 1 Familia de objetos. Portanto mais de 1 objeto.

CRIA 1 FAMÍLIA DE OBJETO

padroesdeprojeto.com.br Abstract Factory Página 31


Abstract Factory
<<interface>>
TrajeFactory é a Abstract Factory.
RoupaTronco

TrajeFactoryFormal e TrajeFactoryCasual são classes Factories Concretas que


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

TrajeFactory
Camisa Camiseta

criarRoupaTronco(): RoupaTronco

criarRoupaPernas(): RoupaPernas

criarRoupaPes(): RoupaPes

<<interface>>
RoupaPernas

TrajeFactoryFormal TrajeFactoryCasual

criarRoupaTronco(): Camisa criarRoupaTronco(): Camiseta Calcas Bermuda

criarRoupaPernas(): Calcas criarRoupaPernas(): Bermuda

criarRoupaPes(): Sapatos criarRoupaPes(): Tenis

<<interface>>
RoupaPes

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

os objetos das classes


Camiseta, Bermuma e
Tenis.

padroesdeprojeto.com.br Abstract Factory Página 32


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

padroesdeprojeto.com.br Abstract Factory Página 33


DIAGRAMA DE CLASSES ILUSTRADO
Cliente

tff = new TrajeFactoryFormal(); <<interface>>


criarManequimFormal(): Manequim
RoupaTronco
manequim = new Manequim(tff);
criarManequimCasual(): Manequim

tfc = new TrajeFactoryCasual();


Manequim manequim = new Manequim(tfc);
Camisa Camiseta

tronco: RoupaTronco
pernas: RoupaPernas
pes: RoupaPes

construtor(TrajeFactory factory)

<<interface>>
RoupaPernas

TrajeFactory

criarRoupaTronco(): RoupaTronco

criarRoupaPernas(): RoupaPernas Abstract Factory


Calcas Bermuda

criarRoupaPes(): RoupaPes

TrajeFactoryFormal TrajeFactoryCasual
<<interface>>
criarRoupaTronco(): Camisa criarRoupaTronco(): Camiseta RoupaPes

criarRoupaPernas(): Calcas criarRoupaPernas(): Bermuda

criarRoupaPes(): Sapatos criarRoupaPes(): Tenis

Factory Concreta Factory Concreta Sapatos Tenis

padroesdeprojeto.com.br Abstract Factory Página 34


Facade
Padrão Estrutural
POO

06 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Facade Página 35
FACADE
Padrão Estrutural

DEFINIÇÃO: O padrão Facade fornece uma interface unificada PROBLEMA: Deseja-se


para um conjunto de interfaces em um subsistema. O Facade fornecer uma interface
define uma interface de nível mais alto que facilita a utilização do simplificada para a
subsistema. montagem de um robô
composto por muitas
partes.
O Cliente precisa de um Robô.

Para montar um robô o cliente precisa conhecer cada Cliente


classe que faz parte do subsistema que cria um robô. Tronco criar

montarRobo Cabeca criar


O Cliente precisa conhecer toda a complexidade do BracoEsquerdo criar
processo de montagem de um robô. BracoDireito criar
Cliente depende PernaEsquerda criar
de 6 classes
PernaDireita criar

Cabeca

BracoEsquerdo
criar
Cliente2
criar
BracoDireito
ClienteN
Tronco
criar
O Cliente 2 ainda não precisa
de um robô. Porém, se ele vir criar montarRobo
a 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

padroesdeprojeto.com.br Facade Página 36


DIAGRAMA DE CLASSES ILUSTRADO

1
Cliente Cliente2
... ClienteN
A classe Facade externaliza todo o subsistema
robô de uma forma simplificada.

2 2 Não importa quantos clientes


precisam de um robô, eles Ela fornece uma fachada simplificada para algo
2 podem sempre recorrer à classe que é complexo.
1 Facade.
Facade
Graças à classe Facade os clientes não
Tronco criar precisam mais se preocupar com o processo de
montarRobo
Cabeca criar montagem de um robô.
BracoEsquerdo criar
BracoDireito criar
PernaEsquerda criar 2
PernaDireita criar
Os clientes dependem apenas da classe Facade.
Cabeca
Esse é o E não mais das 6 classes como antes da classe
BracoEsquerdo
criar subsistema de Facade Existir.
robô.
criar

BracoDireito 3
Tudo o que é
criar Embora a classe Facade simplifique o acesso, as
Tronco refente a robô
classes do subsistema continuam acessíveis. O
fica aqui dentro.
criar Facade é uma alternativa simplificada.

Veja por exemplo que a classe ClienteEspecifico


precisa apenas das pernas do robô. Ela pode
PernaEsquerda PernaDireita
acessar as classes diretamente, sem a
criar criar intermediação da classe Facade.

Um subsistema pode possuir mais de uma classe de


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

3 É 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 todas as classes do subsistemas.

padroesdeprojeto.com.br Facade Página 37


Template Method
Padrão Comportamental
POO

07 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Template Method Página 38
TEMPLATE METHOD
Padrão Comportamental

DEFINIÇÃO: O padrão Template Method define o esqueleto de PROBLEMA: Deseja-se


um algoritmo dentro de um método, transferindo alguns de seus garantir que os ingredientes
passos para subclasses. O Template Method permite que as dos hambúrgueres sejam
subclasses redefinam certos passos de um algoritmo sem alterar montados sempre na
a estrutura do mesmo. mesma ordem, porém os
ingrediente podem variar.

Os métodos de Hamburguer podem ser concretos


ou abstratos.
Hamburguer
Quando forem concretos suas implementações
serão opcionais para as subclasses de
Hamburguer
pao
Hamburguer. Elas poderão escolher se desejam
ou não sobrescreve-los. acompanhamento

Quando forem abstratos, as subclasses de queijo


Hamburguer serão obrigadas a implementar os
métodos. hambuguer

salada
O algoritmo é: TemplateMethod
1º - Adicione o pão cortado ao meio
Esse é o método responsável por definir o
2º - Adicione o Acompanhamento
1º algoritmo que utiliza os métodos da classe
3º - Adicione o Queijo
Hambúrguer.
4º - Adicione o Hambúrguer 2º
5º - Adicione a Salada 3º Podemos dizer que ele é a receita do
TemplateMethod = Método Molde 4º hambúrguer.

5º O Template Method se preocupa apenas com o


algoritmo (receita). Quais tipos de ingredientes
escolher e como prepara-los são
responsabilidade dos demais métodos.

padroesdeprojeto.com.br Template Method Página 39


DIAGRAMA DE CLASSES ILUSTRADO

Vamos assumir que:


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

São abstratos. Isso permite que


o Template Method possa
invocar métodos cujas
implementações ainda nem
existem.
Implementa Implementa Implementa
Tais implementações serão
4 5 6
concretizadas nas subclasses de
Hamburguer.
Utiliza o padrão Utiliza o padrão Utiliza o padrão

Sobreescreve
Sobreescreve

padroesdeprojeto.com.br Template Method Página 40


Adapter
Padrão Estrutural
POO

08 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Adapter Página 41
ADAPTER
Padrão Estrutural

DEFINIÇÃO: Converter uma interface de uma classe (incompatível) PROBLEMA: Para ter uma
para outra interface que o cliente espera encontrar. O Adapter conexão mais rápida
busca permitir que classes com interfaces incompatíveis deseja-se ligar um cabo
trabalhem juntas. Ethernet em um notebook
que possui apenas portas
USB.

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

padroesdeprojeto.com.br Adapter Página 42


DIAGRAMA DE CLASSES ILUSTRADO

1 5 6
Essa é nossa interface ALVO. O Aqui acontece o processo de É comum existir cenários onde 1
CLIENTE espera receber uma ADAPTAÇÃO. Cada método do ADAPTER método do ADAPER é equivalente
interface que tenha 1 método chama seu equivalente na classe a N métodos da classe
laranja, 1 vermelho e outro verde. ADAPTADA, recupera o retorno e o ADAPTADA e vice-versa.
fornece ao CLIENTE seguindo as
restrições impostas pela interface ALVO.

Repare que o método verde é identico na


6
classe ADAPTADA, ele não precisa de
adaptação

2 O cliente consumidor do
Nossa interface alvo é
A classe que temos não possui os padrão de projeto é
equivalente ao notebook equivalente a porta USB
métodos esperados pelo cliente.
As cores não batem.
4 Alvo
1
Cliente

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)

padroesdeprojeto.com.br Adapter Página 43


State
Padrão Comportalmental
POO

09 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br State Página 44
STATE
Padrão Estrutural

DEFINIÇÃO: O padrão de projeto State permite que um objeto


PROBLEMA: Gerenciar as
altere o seu comportamento quando o seu estado interno muda.
interações do usuário com um
O objeto parecerá ter mudado de classe.
Smartphone de acordo com
seus possíveis estados.

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.

padroesdeprojeto.com.br State Página 45


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.

padroesdeprojeto.com.br State Página 46


O padrão State sugere que cada estado se torne um objeto de estado. Para existir um
objeto é preciso que exista uma classe.

Bloqueado Desbloqueado Travado

Senha não
Validada

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()

padroesdeprojeto.com.br State Página 47


Além disso, todos os objetos de estado devem ser exergados da mesma forma pelo
Senha não sistema. Eles precisam ter um tipo em comum. Todos precisam implementar uma
Validada mesma interface.

<<interface>>
Senha
State
Validada
senhaValidada()
Bloqueado Desbloqueado
senhaNaoValidada()
Bloquear
bloquear()

Travar travar()
Destravar
destravar()

Travado

Cada uma das classes de estado trata as


transições da forma que lhe convêm.
Bloqueado Desbloqueado Travado
Por exemplo, no método senhaNaoValidada da
classe Bloqueado pode existir um contador que ao senhaValidada() senhaValidada() senhaValidada()

atingir o valor 3 chama o método travar. senhaNaoValidada() senhaNaoValidada() senhaNaoValidada()

bloquear() bloquear() bloquear()


No método travar pode existir um timer que após
10 segundos chama o método destravar. travar() travar() travar()

destravar() destravar() destravar()


Por outro lado, as funcionalidades descritas acima
não fazem 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

padroesdeprojeto.com.br State Página 48


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.

padroesdeprojeto.com.br State Página 49


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.

padroesdeprojeto.com.br State Página 50


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 this.smartphone.setEstadoAtual(this.smartphone.destravadoState);
de classes que o da página }
anterior. Desbloqueado

Alguns detalhes da classe smartphone: Smartphone


Smartphone e da interface
State foram ocultados para contrutor(Smartphone smartphone) this.smartphone = smartphone;
otimizar o espaço na senhaValidada()
página.
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 Seria mais adequado que


a classe Smartphone
ver as informações em um tivesse getters para os
tamanho maior. estados. Mas vamos
Bloqueado manter as coisas simples
this.smartphone = smartphone; por aqui.
smartphone: Smartphone

contrutor(Smartphone smartphone) //Troca o estado para Desbloqueado;


this.smartphone.setEstadoAtual(this.smartphone.desbloqueadoState);
senhaValidada() Senha não
Validada
senhaNaoValidada()
if (errou a senha 3 vezes) { //Pseudocódigo Senha
bloquear() this.travar(); //chama o método travar Validada

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


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

//Troca o estado do Smartphone para travado;


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

padroesdeprojeto.com.br State Página 51


Observer
Padrão Comportalmental
POO

10 Rabiscando
PADRÕES DE
PROJETO
padroesdeprojeto.com.br Observer Página 52
OBSERVER
Padrão Comportamental

DEFINIÇÃO: O Observer é um padrão de projeto de software que


PROBLEMA: Manter objetos
define uma dependência um-para-muitos entre objetos, de modo
leitores atualizados sobre as
que quando um objeto muda seu estado, todos os seus
noticias que outro objeto
dependentes são notificados e atualizados automaticamente.
jornalista publica.

O problema da abordagem ao lado é a


sobrecarga de solicitações Esse objeto não
deseja receber as
desnecessárias ao objeto Jornalista. novidades Esse objetos Leitores
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 algumdaa 10s foi lançada.
novidade? 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 Aqui, muitos objetos dependem de 1 único objeto. Muitos Leitores dependem de apenas 1 Jornalista.
solicitações. (Dependencia muitos-para-um)

padroesdeprojeto.com.br Observer Página 53


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

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

e
o novidad
Objeto que gera o assunto de interesse tenh Objeto Leitor A
(Subject) agora eu
Hey,
Os objetos Leitores
o novidade
Hey, agora eu tenh (Observers) podem ser
Hey, agora eu
tenho novida
instâncias de classes
de Objeto Leitor B diferentes
Hey,
agor
a eu
Objeto Leitor A Objeto Jornalista tenh
o no LeitorTipo2
vidad
Objeto Leitor B e
Objeto Leitor C
Objeto Leitor C senhaValidada()

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

padroesdeprojeto.com.br Observer Página 54


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
senhaValidada() 2 jornalista: Jornalista | null
senhaValidada()

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

senhaValidada() observer)
desinscrever(Observer

notificar()

padroesdeprojeto.com.br Observer Página 55


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
senhaValidada() jornalista: Jornalista| null
senhaValidada()
popularmente conhecidos. Saiba que aqui você pode, e deve, utilizar a
estrutura de dados que achar mais apropriada ao seu problema. listaObservers: array
senhaValidada() 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 //O Jornalista pode se passado no construtor do observador
proposta de desing de código. public function construtor (Jonalista jornalista) {
O importante é remover o objeto observer a "lista" de Raramente você seguira a this.jornalista = jornalista;
objetos a serem notificados. implementação pura do padrão.
this.jornalista.inscrever(this);
*/ }
É comum que existam diversas
variações e adequações do
código do padrão, porém, //Para um maior nível de abstração
para cada objeto observer contido na listaObservers () { mantendo a ideia central que o //Também, é possível esperar o super tipo Subject no construtor
/*Em algum lugar de seu código o objeto produz uma padrão dita. //Nesse caso, o tipo do atributo no diagrama deveria ser trocado para "Subject | null"
noticia (string) e a envia para todos os observadores public function construtor (Subject jornalista) {
que se inscreverem em sua lista.*/
Veja ao lado algumas formas
this.jornalista = jornalista;
diferentes de implementar o
chamar o método receberNoticia(noticia); this.jornalista.inscrever(this);
processo de atribuição de um
} objeto Jornalista ao atributo }
jornalista dos Leitores (1 e 2).
//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) { Também repare no processo de public function observar (Subject jornalista) {
observer.receberNoticia(noticia); inscrição dos Leitores this.jornalista = jornalista;
} (observers) em um objeto this.jornalista.inscrever(this);
Jornalista. }

padroesdeprojeto.com.br Observer Página 56


Obrigado por ler esse e-book

Espero ter te ajudado a avançar em seus estudos.

Quando entrei na universidade, meu objetivo inicial era ser professor universitário. Ao
POO
conversar com alguns professores, que se tornaram meus amigos, notei que a vida
acadêmica não era exatamente o que eu queria.

Sempre tive prazer em ensinar as pessoas e encontrei na internet um meio para


compartilhar meu conhecimento.

Te incentivo a fazer o mesmo, quanto mais conhecimento, melhor. Indique esse e-book
para as pessoas que acha que farão bom uso dele, assim como você.

Caso tenha alguma dúvida, sugestão, critica ou elogio sinta-se a vontate para escrever
para o e-mail abaixo. Darei o meu melhor pra te responder.

vinicius@padroesdeprojeto.com.br

padroesdeprojeto.com.br Página 57
Conheça o treinamento completo

Caso queira aprofundar ainda mais os seus conhecimento sobre os Padrões de Projeto
(Design Patterns). Eu te convido a conhecer o treinamento Rabiscando Padrões de
Projeto.
Rabiscando
POO
PADRÕES DE
PROJETO
Lá eu faço uma "Dissecação" completa de todos os 23 Design Patterns que foram
catalogados pela Gang of Four (GoF).

Você também terá a oportunidade de ver os padrões de projeto sendo aplicados para
resolver problemas reais, muito próximos ao que encontramos no nosso dia a dia como
desenvolvedores de software.

CONHEÇER
AGORA

padroesdeprojeto.com.br Página 58
Rabiscando

Roadmap de tudo o que você PADRÕES DE


PROJETO

aprenderá SABER MAIS


CLIQUE AQUI

INTRODUÇÃO O PROJETO
Como REVISÃO DE O QUE SÃO PAdrões Conhecendo o
Abertura SUPORTE
ESTUDAR CONCEITOS de Projeto projeto pŕatico

ESTRUTURAIS Comportamentais
parte 1 parte 1
Template
FACADE DECORATOR ADAPTER STATE OBSERVER Strategy
Method

CRIACIONAIS Comportamentais ESTRUTURAIS


parte 1 parte 2 PARTE 2
FACTORY ABSTRACT CHAIN OF
BUILDER ITERATOR COMMAND BRIDGE
METHOD FACTORY RESPONSIBILITY

Comportamentais
DEMAIS PADRÕES parte 3
PROTOTYPE SINGLETON MEDIATOR MEMENTO VISITOR COMPOSITE PROXY

VOCê dominando os
AULA BÔNUS
ENCERRAMENTO padrões de projeto
INTERPRETER
(CRIANDO O PARSER)
Flyweight INTERPRETER Aula FINAL CERTIFICADO

padroesdeprojeto.com.br Página 59
O QUIZ FINAL

CLIQUE AQUI
PARA RESPONDER

Chegou a hora de medir o resultado dos seus estudos.

Se você acertar pelo menos 7 das 10 questões já pode considerar que seus
estudos foram um grande sucesso!

padroesdeprojeto.com.br Página 60
AVALIAÇÃO DO E-BOOK

CLIQUE AQUI
PARA AVALIAR

Sua Opinião é muito importante!

padroesdeprojeto.com.br Página 61
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, POO


surgem novos códigos para dar
manutenção.

Pelo bem do seu eu do futuro,


Pelo bem da sua equipe

escreva bons códigos.

Até a próxima!
padroesdeprojeto.com.br Página 62

Você também pode gostar