padrões de projeto aula 6 – padrão factory method

22
Padrões de Projeto Aula 6 – Padrão Factory Method

Upload: branca-flor-stachinski-bayer

Post on 07-Apr-2016

216 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Padrões de Projeto Aula 6 – Padrão Factory Method

Padrões de ProjetoAula 6 – Padrão Factory Method

Page 2: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

PADRÃO FACTORY

Sobre delegar as criações de objetos para fábricas.

Page 3: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Um dos principais princípios

Programe para interfaces/superclasses.

Por que?

Page 4: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Pizzaria Sapore Rio Tinto

• Para entendermos o padrão Factory, vamos implementar um sistema para a pizzaria Sapore Rio Tinto. Para fazer uma pizza, nós basicamente a preparamos, assamos, fatiamos e a embalamos.

Pizza orderPizza(){Pizza pizza = new Pizza();

pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;

}

Programando para superclasses.

Page 5: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

• Mas a Sapore Rio Tinto vai vender mais do que um tipo de pizza...

Pizza orderPizza(String type){Pizza pizza;if(type.equals("Moussarela"))

pizza = new Moussarela();else if(type.equals("Pepperoni"))

pizza = new Pepperoni();else if(type.equals("Franpiry"))

pizza = new Franpiry();

pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;

}

agora estamos passando o tipo de Pizza

com base no tipo de pizza, instanciamos a classe concreta

Quando tivermos uma pizza iremos prepará-la, assá-la, fatiá-la e embalá-la. Cada subtipo de pizza sabe como se preparar (Strategy).

Page 6: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

A Franpiry não está saindo muito... Vamos tirá-la do cardápio e adicionar a Marguerita.

Pizza orderPizza(String type){Pizza pizza;if(type.equals("Moussarela"))

pizza = new Moussarela();else if(type.equals("Pepperoni"))

pizza = new Pepperoni();else if(type.equals("Franpiry"))

pizza = new Franpiry();else if(type.equals(“Margherita"))

pizza = new Margherita();

pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;

}

Isto varia na medida em que o cardápio muda.

Isto esperamos que fique igual. Toda pizza passa pelo mesmo processo.

Isto não é nada bom!

Page 7: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Outro princípio

Identifique os aspectos de seu sistema que variam e separe-os dos que permanecem iguais.

Page 8: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Aplicando o princípio...

Pizza orderPizza(String type){Pizza pizza;

pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;

}if(type.equals("Moussarela"))

pizza = new Moussarela();else if(type.equals("Pepperoni"))

pizza = new Pepperoni(); else if(type.equals(“Margherita")

pizza = new Margherita();

SimplePizzaFactory

Colocamos esse código em uma classe que só vai se preocupar em como criar pizzas. Se qualquer outro objeto quiser criar uma pizza ele deve recorrer a esta classe.

Não resolve 100% dos nossos problemas mas estamos no caminho certo... Aumentamos, um pouquinho, a coesão do sistema.

Page 9: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

public class SimplePizzaFactory {public Pizza createPizza(String type){

Pizza pizza = null;if(type.equals("moussarela"))

pizza = new Moussarela();else if(type.equals("margherita"))

pizza = new Margherita();else if(type.equals("pepperoni"))

pizza = new Pepperoni();return pizza;

}}

Vantagens: maior coesão e manutenção mais fácil

Vários clientes podem usar a fábrica e as alterações ficam localizadas no código encapsulado.

Page 10: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

public class PizzaStore {private SimplePizzaFactory pizzaFactory;public PizzaStore(SimplePizzaFactory pizzaFactory)

{this.pizzaFactory = pizzaFactory;

}public Pizza orderPizza(String type, int slices){

Pizza pizza = pizzaFactory.createPizza(type);pizza.prepare();pizza.bake();pizza.cut(slices);pizza.box();return pizza;

}}

agora PizzaStore tem uma referência a SimplePizzaFactory

PizzaStore recebe a fábrica no construtor

O método orderPizza agora usa a fábrica para criar suas pizzas

Note que agora não existe mais o modificador new. As instanciações concretas ficam na fábrica.

Page 11: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

The Simple Factory

Page 12: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Considerações sobre a Simple Factory

• Não é um padrão, é um programming idiom. (Mais sobre programming idioms aqui)

• É legal pois torna nosso código coeso e centraliza possíveis alterações futuras em um único lugar, mas não resolve todos os problemas de flexibilidade

• Para isto, devemos recorrer a um dos seguintes padrões: Factory Method e Abstract Factory

Page 13: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Franqueando a Sapore RT• A Sapore RT foi um sucesso! Agora queremos abrir novas franquias em João Pessoa e

em Campina Grande. Como franqueador devemos garantir a qualidade de nosso produto, portanto, queremos que cada franquia use nosso código testado e aprovado.

• Mas, devido às diferenças culturais, cada franquia pode querer oferecer estilos diferentes de pizza, dependendo de onde a loja esteja e do gosto dos apreciadores locais de pizza.

• Sugestões de design?

Massa média, molho temperado e muito queijo.

RioTintoFactory

JoaoPessoaFactory

Massa fina, molho temperado e pouco queijo.

Page 14: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

• Problems?• Uma SimpleFactory pode ser utilizada com outra Store, outra classe que não a

PizzaStore.• Logo, não há garantia que as franquias sigam o modelo de pizzaria proposto

pelas pizzarias Sapore. As outras franquias poderiam, por exemplo: assar de modo diferente, esquecer de fatiar a pizza, embalar com caixas de terceiros.

• Isso não é o que queremos. Isto descaracteriza a ideia de uma franquia... A classe PizzaStore e a criação das pizzas não estão mais acopladas como o esperado. Esse é um dos poucos casos em que o acoplamento se faz necessário.

• Para este caso nós desejamos o acoplamento (para garantir que as franquias sigam os mesmos processos com a alta qualidade das Pizzarias Sappore) mas também a flexibilidade (para que seja possível criar diferentes fábricas com diferente peculiaridades regionais).

RioTintoFactory rtFactory = new RioTintoFactory();PizzaStore rtStore = new PizzaStore(rtFactory);rtStore.order("Moussarela");

JoaoPessoaFactory jpFactory = new JoaoPessoaFactory();PizzaStore jpStore = new PizzaStore(jpFactory);jpStore.order("Moussarela");

Page 15: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

• Pensando abstratamente, não há um acoplamento entre a classe que usa a fábrica (PizzaStore) e a própria fábrica.

• Como contornar este problema?• A SimpleFactory tornou o código da pizzaria fechado a

modificações mas quebrou o vínculo entre a Pizza e a Pizzaria.

• Vamos criar um forma de estabelecer um vínculo entre a Pizzaria e a forma de instanciar as pizzas mas mantendo a flexibilidade.

Page 16: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

The Method Factory Pattern

public abstract class PizzaStore {public Pizza orderPizza(String type, int slices){

Pizza pizza = createPizza(type);pizza.prepare();pizza.bake();pizza.cut(slices);pizza.box();return pizza;

}

protected abstract Pizza createPizza(String type);}

agora PizzaStore é abstrata createPizza volta para PizzaStore, ao invés de estar num objeto de fábrica

A criação do objeto de fábrica fica por conta deste método, o método Factory. Cabe às subclasses decidirem o que de fato é instanciado.

Perceba que PizzaStore é fechado para modificação mas flexível. Por que?

As novas lojas não interferem no restante do processo.

Page 17: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Franquias Sapore• As subclasses de PizzaStore (as franquias) é que decidem quais

tipos de Pizzas criar• Mas a forma do pedido da pizza segue o padrão estabelecido

para todas as franquias (ver método orderPizza)• orderPizza é um método cliente do instanciador createPizza

Cada franquia cria uma classe concreta que implementa createPizza Produto abstrato

Exemplo de produto concreto

Page 18: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Definição• Todos os padrões factory encapsulam a criação de objetos;• O padrão Factory Method encapsula a criação de objetos

deixando as subclasses decidirem quais objetos criar;• Utilize o padrão quando uma classe precisa instanciar

subclasses de uma classe C que ainda não foram definidas;• Utilize esse padrão quando precisar delegar a

responsabilidade de criar objetos.O padrão Factory Method define uma

interface para criar um objeto, mas permite às classes decidir qual classe instanciar.

O Factory Method permite uma classe delegar a instanciação para subclasses.

Page 19: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Terminologia e Estrutura

Page 20: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Prática• Chega de blablabla... Vamo botar a mão na massa! • Vamos implementar o sistema da Sapore Pizzaria.• Considere as seguintes especificações:

Sabor Rio Tinto João Pessoa

Margherita Manjericão, massa média, muito queijo, molho temperadoTempo de forno: 7Temperatura: 550ºC

Manjericão, massa fina, pouco queijo, molho temperadoTempo de forno: 10Temperatura: 500ºC

Pepperoni Pepperoni, muito queijo, molho apimentadoTempo de forno: 10Temperatura: 500ºC

Pepperoni, muito queijo, molho apimentadoTempo de forno: 10Temperatura: 500ºC

Moussarela Muito queijoTempo de forno: 10Temperatura: 500ºC

Pouco queijoTempo de forno: 8Temperatura: 450ºC

Page 21: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Page 22: Padrões de Projeto Aula 6 – Padrão Factory Method

Padr

ões d

e Pr

ojet

o - F

acto

ry M

eth

od

Referências• [1] O cenário de pizzarias é abordado no capítulo 4 do livro

“Padrões de Projeto – Use a Cabeça!”