Anda di halaman 1dari 43

I N S T I T U TO F E D E R A L D E E D U C A O, C I N C I A E T E C N O LO G I A D E S O PAU LO ( I F S P )

C A M P U S S O C A R LO S

PADRES DE PROJETO: MTODO FBRICA


Programao Orientada a Objetos (POO)
Prof. Dr. Lucas Bueno R. Oliveira

1 Semestre
2016

PADRES VISTOS AT AQUI


Padro Strategy
Separa e encapsula os aspectos do seu sistema que variam dos aspectos que
permanecem os mesmos.

Padro Observer
Define a dependncia 1:N entre objetos para que quando um objeto mude de
estado, todos os seus dependentes sejam avisados e atualizado automaticamente.

Padro Facade
Interface simples para acesso a um subsistema.

Padro Decorator
Adiciona responsabilidades a um objeto dinamicamente.

Padro Singleton
Garante que uma classe tenha apenas uma instncia, oferecendo um ponto de
acesso global a ela.

TIPOS DE PADRES DE PROJETO


Padres de Criao

Padres de Estrutura

Padres de Estrutura

Abstract Factory

Adapter

Command

Builder

Bridge

Interpreter

Factory Method

Composite

Iterator

Prototype

Decorator

Mediator

Singleton

Facade

Memento

Flyweight

Observer

Proxy

State
Strategy
Template Method
Visitor

Chain of Resposibility

PADRO MTODO FBRICA

O USO DO NEW
Cada vez que invocamos o new, deixamos de programar
para a interface e passamos a programar para o cdigo
Pato pato = new PatoCabecaVermelha();

Mesmo que a nossa varivel pato seja de um tipo


interface (Pato), nossa classe que contm essa clusula
depende da classe concreta PatoCabecaVermelha.
Pato

PatoCabecaVermelha

O USO DO NEW
Quando temos uma srie de classes concretas relacionadas,
no incomum que vejamos um cdigo como esse:
Pato pato;
if (picnic) {
pato = new PatoReal();
} else if (casa) {
pato = new PatoDecoracao();
} else if (banheira) {
pato = new PatoBorracha();
}

Nesses casos, no sabemos, at o tempo de execuo, qual


a classe que precisamos instanciar.
6

PROBLEMAS?
Pato pato;
if (picnic) {
pato = new PatoReal();
} else if (casa) {
pato = new PatoDecoracao();
} else if (banheira) {
pato = new PatoBorracha();
}

Problemas nessa implementao?


Qualquer mudana implica na modificao desse cdigo:

Se criarmos uma nova classe de patos, precisamos mudar o cdigo.


Se mudarmos as condies de uso das classes, nosso cdigo precisa ser
mudado.
7

PRINCPIOS DE DESIGN
Violamos alguns princpios no nosso cdigo anterior:
Princpio do aberto fechado.
Uma classe deve estar aberta para extenso, mas fechada para
modificao.

Princpio do encapsulamento
Deve-se sempre encapsular o que varia.

PROGRAMANDO PARA UMA INTERFACE...


A importncia de programar para uma interface se faz
presente!
Programando para uma interface, voc se previne de futuras mudanas
no seu cdigo.
Se o seu cdigo escrito para uma interface, ento ele funcionar
para qualquer classe que implemente aquela interface, por meio do
polimorfismo.
Se o seu cdigo escrito para classes concretas, sofrer mudanas
todas as vezes que as classes concretas tambm sofrerem.

PROBLEMA DE HOJE: PIZZARIA


Voc tem uma pizzaria e, consequentemente, produz vrias
pizzas.
Obviamente, cada pizza produzida/criada aps um pedido
especfico de um cliente.

Com o crescimento do negcio, voc abandonou o bloco de papel


e resolveu criar um sistema para gesto da sua pizzaria.

10

INICIANDO COM A NOSSA PIZZARIA


Considere nossa pizzaria. Provavelmente ela teria um cdigo
parecido com este:
public class Pizzaria {
public Pizza realizaPedido() {
Pizza pizza = new Pizza();
pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();

Precisamos ter mais de


um tipo de pizza, no
apenas uma

return pizza;

}
}

11

INICIANDO COM A NOSSA PIZZARIA


Determinando o tipo apropriado de pizza e depois a criando:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;
if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}
pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;

Agora passamos o tipo


de pizza para o pedido
Com base no tipo de pizza,
instanciamos a classe concreta correta
e atribumos a varivel de instncia
Pizza. Observe que cada pizza deve
implementar a interface Pizza

Quando tivermos a pizza,


vamos prepar-la. Cada
subtipo sabe como
preparar a si prpria

}
}

12

IDENTIFICANDO OS ASPECTOS QUE VARIAM


Determinando o tipo apropriado de pizza e depois a criando:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;

if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}
pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();

Se voc quiser, por exemplo, adicionar mais


pizzas ao cardpio? E se quiser retirar?

return pizza;
}
}

13

IDENTIFICANDO OS ASPECTOS QUE VARIAM


Determinando o tipo apropriado de pizza e depois a criando:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;
if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}

Criao

Como a seleo de pizzas


muda com o tempo, esse
cdigo dever ser modificado
muitas vezes

pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;
}
}

14

IDENTIFICANDO OS ASPECTOS QUE VARIAM


Determinando o tipo apropriado de pizza e depois a criando:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;
if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}

pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;

Isso o que esperamos que


permanea sempre igual.

Preparao

15

IDENTIFICANDO OS ASPECTOS QUE VARIAM


Determinando o tipo apropriado de pizza e depois a criando:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;
if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}

Como a seleo de pizzas


muda com o tempo, esse
cdigo dever ser modificado
muitas vezes

Criao

pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;

Isso o que esperamos que


permanea sempre igual.

Preparao

}
}

16

IDENTIFICANDO OS ASPECTOS QUE VARIAM


Agora sabemos o
que varia. Talvez
chegou a hora de
encapsularmos isso.

17

ENCAPSULANDO A CRIAO
Levar a criao para um objeto preocupado apenas com isso:
public class Pizzaria {
public Pizza realizaPedido (String tipo) {
Pizza pizza;

Primeiro tiramos o trecho


de criao das pizzas
pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;
}
}

if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa"))
{
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango)) {
pizza = new PizzaFrango();
}

Depois levamos ao objeto responsvel


pela criao. Sempre que algum
precisar criar uma pizza, pra esse
objeto que ele deve recorrer.

FabricaSimplesDePizza

18

ENCAPSULANDO A CRIAO
Verificamos o que varia: a criao. Logo, vamos coloc-la
em uma classe separada:
public class FabricaSimplesDePizza {

Essa nossa nova classe. Ela


tem uma tarefa na vida: criar
pizzas para seus clientes

public Pizza criaPizza(String tipo) {


Pizza pizza = null;
if (tipo.equals("mussarela")) {
pizza = new PizzaMussarela();
} else if (tipo.equals("calabresa")) {
pizza = new PizzaCalabresa();
} else if (tipo.equals("frango")) {
pizza = new PizzaFrango();
}
return pizza;
}
}

Definimos um mtodo para


criao dentro da fbrica.
Este o mtodo que todos os
clientes iro usar para
instanciar novos objetos

Trecho de cdigo que


tiramos de Pizzaria

19

PERGUNTA CAPCIOSA
Qual a vantagem disso? Parece que estamos empurrando o
problema para outro objeto.
Lembre-se que a nossa FabricaSimplesDePizza pode ter muitos clientes,
e no apenas a Pizzaria. Pode-se ter, por exemplo, uma
PizzariaDelivery.
Ao encapsular a criao em uma classes, temos apenas um lugar para
fazer a modificao quando algo alterado.

20

SIMPLE FACTORY
Pizzaria

Definimos como classes


abstratas, com algumas
implementaes teis que
podem ser substitudas
<<abstract>>
Pizza

FabricaSimplesDePizza
criaPizza() : Pizza

fabrica: FabricaSimplesDePizza
realizaPedido() : Pizza

Cliente da fbrica
de pizzas

Nossos produtos concretos,


que devem ser subtipos de
Pizza

Fbrica onde criamos as pizzas.


Deve ser a nica parte da nossa
aplicao que refere-se a
classes concretas de pizza

PizzaMussarela

getNome()
preparar()
assar()
cortar()
empacotar()

PizzaCalabresa

PizzaFrango

21

EXERCCIO I
Reimplemente a classe Pizzaria, utilizando a classe
FabricaSimplesDePizza para a criao das pizzas
<<abstract>>
Pizza

Pizzaria
fabrica: FabricaSimplesDePizza
realizaPedido(String tipo):
Pizza

FabricaSimplesDePizza
criaPizza(String tipo): Pizza

public Pizza realizaPedido(String tipo) {


Pizza pizza = fabrica.criaPizza(tipo);
pizza.preparar();
pizza.assar();
pizza.cortar();
PizzaMussarela
pizza.empacotar();
return pizza;
}

getNome()
preparar()
assar()
cortar()
empacotar()

PizzaCalabresa

PizzaFrango

22

FACTORY METHOD
Para entender a importncia do Factory Method, vamos
imaginar que nossa loja est se expandindo...
Novas lojas pelo mundo: Roma, Londres...

Cada nova loja precisa de uma fbrica prpria para


atender s necessidades do cliente local.
Queremos modificar a maneira que algumas pizzas so criadas
Por exemplo: Determinada cidade a massa mais fina que em outra

Queremos, entretanto, que o processo de preparao continue o


mesmo.
As pizzas esto fazendo sucesso, ento no vamos mexer nisso.

23

FACTORY METHOD
O padro de projeto Factory Method permite que faamos
isso:
Colocando cdigo abstrato em uma superclasse.
Colocando o cdigo para criao de objetos em uma subclasse.

Dessa forma...
Pizzaria se torna uma classe abstrata com um mtodo abstrato
criarPizza()
Criamos subclasses que sobrescrevem o mtodo criarPizza() para cada
regio.

24

FACTORY METHOD
O que varia entre as pizzarias de diferentes cidades o
estilo das pizzas:
Cada subclasse substitui o
mtodo criaPizza() e utiliza
mtodo realizaPedido()
definido em Pizzaria

<<abstract>>
Pizzaria
criaPizza(): Pizza
realizaPedido(): Pizza

PizzariaRoma
criaPizza(): Pizza

PizzariaLondres
criaPizza(): Pizza

25

FACTORY METHOD
Classe abstrata Pizzaria:
public abstract class Pizzaria {
public abstract Pizza criaPizza(String tipo);
public Pizza realizaPedido(String tipo) {
Pizza pizza = criaPizza(tipo);
pizza.preparar();
pizza.assar();
pizza.cortar();
pizza.empacotar();
return pizza;
}
}

26

FACTORY METHOD
Classe concreta de uma Pizzaria especfica:
public class PizzariaRoma extends Pizzaria {
public Pizza criaPizza(String tipo) {
if (tipo.equals("mussarela")) {
return new PizzaMussarelaEstiloRoma();
} else if (tipo.equals("calabresa")) {
return new PizzaCalabresaEstiloRoma ();
} else if (tipo.equals("frango")) {
return new PizzaFrangoEstiloRoma ();
}
}
}

27

FACTORY METHOD
Classes de Criao:
<<abstract>>
Pizzaria
criaPizza(): Pizza
realizaPedido(): Pizza

PizzariaRoma

PizzariaLondres

criaPizza(): Pizza

criaPizza(): Pizza

Classe de criador abstrata.


Ela define um mtodo fabrica
abstrato: criaPizza()

Como cada franquia recebe


sua prpria subclasse, ela fica
livre para criar a pizza da
maneira que desejar

28

FACTORY METHOD
Classes de Produtos:
As fbricas fazem produtos.
No nosso caso, nosso
produto a Pizza
Conjunto de produtos concretos
(pizzas) produzidas em nossas
pizzarias
PizzaMussarelaEstiloRoma
PizzaCalabresaEstiloRoma

<<abstract>>
Pizza
getNome()
preparar()
assar()
cortar()
empacotar()

PizzaMussarelaEstiloLondres
PizzaCalabresaEstiloLondres

29

FACTORY METHOD
Factory Method para nosso problema:
<<abstract>>
Pizzaria
criaPizza(): Pizza
realizaPedido(): Pizza

PizzariaRoma

PizzariaLondres

criaPizza(): Pizza

criaPizza(): Pizza
PizzaMussarelaEstiloRoma
PizzaCalabresaEstiloRoma

<<abstract>>
Pizza
getNome()
preparar()
assar()
cortar()
empacotar()

PizzaMussarelaEstiloLondres
PizzaCalabresaEstiloLondres

30

ESTRUTURA GERAL
O padro Mtodo Factory define uma interface para criar
um objeto, mas deixa as subclasses decidirem qual classe
instanciar.
Creator
factoryMethod() : Product
anOperation()

use

ConcreteCreator
factoryMethod() : ConcreteProduct

Product

ConcreteProduct

create

31

CONSEQUNCIAS
Alm de encapsular os aspectos que variam, permite
tambm criar objetos sem precisar especificar todos os
detalhes necessrios para a criao do mesmo.
Transfere a responsabilidade (e a complexidade) de criao
de objetos de uma classe para outra classe.

32

OUTRO EXEMPLO ...


Voc sabe fabricar cervejas?

OUTRO EXEMPLO ...


public abstract class Cervejaria {
abstract public Cerveja fabricarCerveja();
}
public class CervejariaLagerBeer extends Cervejaria{
public Cerveja fabricarCerveja(){
return new CervejaHeineken();
}
}
public class CervejariaStoutBeer extends Cervejaria{
public Cerveja fabricarCerveja(){
return new CervejaGuinness();
}
}

OUTRO EXEMPLO ...


public class Cerveja {
private double teorAlcoolico;
private int qtdCerveja;
protected double preco;
public int getQtdCerveja(){return qtdCerveja;}
public void setQtdCerveja(int ml){qtdCerveja = ml;}
public double getTeorAlcoolico(){return teorAlcoolico;}
public void setTeorAlcoolico(double ta) {teorAlcoolico = ta;}
public double getPreco(){return preco;}
public void setPreco(double p) {preco = p;}
}

OUTRO EXEMPLO ...


public class CervejaGuinness extends Cerveja{
private boolean lata;
public CervejaGuinness(){}
public boolean isLata() {return lata;}
public void setLata(boolean lt) {lata = lt;}
public double getPreco(){return preco;}
public void setPreco(double p) {preco = p;}
}

OUTRO EXEMPLO ...


public class CervejaHeineken extends Cerveja{
private boolean longNeck;
public CervejaHeineken(){}
public boolean isLongNeck() {return longNeck;}
public void setLongNeck(boolean ln) {longNeck = ln;}
public double getPreco(){return preco;}
public void setPreco(double p) {preco = p;}
}

public class App {


public static void main(String args[]){
//Constroi as cervejarias
CervejariaStoutBeer fabricaGui = new CervejariaStoutBeer();
CervejariaLagerBeer fabricaHei = new CervejariaLagerBeer();
List<CervejaGuinness> fardoGui = new ArrayList<CervejaGuinness>();
CervejaGuinness guinness;
for(int i = 0; i < 12; ++i){
guinness = (CervejaGuinness)fabricaGui.fabricarCerveja();
guinness.setLata(true);
guinness.setPreco(18.90);
guinness.setTeorAlcoolico(6.5);
fardoGui.add(guinness);
}
List<CervejaHeineken> fardoHei = new ArrayList<CervejaHeineken>();
CervejaHeineken heineken;
for(int i = 0; i < 6; ++i){
heineken = (CervejaHeineken) fabricaHei.fabricarCerveja();
heineken.setLongNeck(true);
heineken.setPreco(2.99);// Supermercado %Dia
heineken.setTeorAlcoolico(4.5);
fardoHei.add(heineken);
}
continua ...

public class App {


continuando ...
double precoHei=0;
double precoGui=0;
double teorGui=0;
double teorHei=0;
for(CervejaGuinness g: fardoGui){
precoGui += g.getPreco();
teorGui+=g.getTeorAlcoolico()*500/100;
}
for(CervejaHeineken h: fardoHei){
precoHei += h.getPreco();
teorHei+=h.getTeorAlcoolico()*355/100;
}
System.out.println("O fardo de Guinness custou: "+precoGui
+ " e voc consumiu "+teorGui+" ml de alcool." );
System.out.println("O fardo de Heineken custou: "+precoHei
+ " e voc consumiu "+teorHei+" ml de alcool." );
System.out.println("Se beber, no dirija!");
}
}

EXERCCIO II
Implemente a soluo completa da nossa pizzaria, utilizando o
Factory Method, conforme diagrama abaixo.
<<abstract>>
Pizzaria
criaPizza(): Pizza
realizaPedido(): Pizza

PizzariaRoma

PizzariaLondres

criaPizza(): Pizza

criaPizza(): Pizza

<<abstract>>
Pizza
getNome()
preparar()
assar()
cortar()
empacotar()

PizzaMussarelaEstiloLondres
PizzaMussarelaEstiloRoma

PizzaCalabresaEstiloLondres

PizzaCalabresaEstiloRoma

40

PARA REFLETIR...
Para quais objetos do cotidiano da programao seria
interessante utilizar o padro Factory Method?

41

REFERNCIAS
Use a Cabea Padres de Projeto

Notas de aula do Professor Jorge Cutigi

42

43

Anda mungkin juga menyukai