A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Aula 6 – Padrão Factory Method

Apresentações semelhantes


Apresentação em tema: "Aula 6 – Padrão Factory Method"— Transcrição da apresentação:

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

2 Padrão Factory Sobre delegar as criações de objetos para fábricas.
Padrões de Projeto - Factory Method

3 Um dos principais princípios
Programe para interfaces/superclasses. Padrões de Projeto - Factory Method Por que esse princípio é tão importante? Resp.: só assim conseguimos praticar o polimorfismo. Por que?

4 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; } Padrões de Projeto - Factory Method Programando para superclasses.

5 Mas a Sapore Rio Tinto vai vender mais do que um tipo de pizza...
agora estamos passando o 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; } com base no tipo de pizza, instanciamos a classe concreta Padrões de Projeto - Factory Method Com esse cenário e com esse código, dá pra a gente ter noção que está sendo aplicado um padrão que nós já estudamos... O Strategy.  Quando tivermos uma pizza iremos prepará-la, assá-la, fatiá-la e embalá-la. Cada subtipo de pizza sabe como se preparar (Strategy).

6 A Franpiry não está saindo muito
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 não é nada bom! Padrões de Projeto - Factory Method Por que isto não é bom? Estamos violando o princípio aberto fechado. As classes devem estar abertas para extensão mas fechadas para modificação. No nosso caso, nós mudaremos esse código com alguma frequência. Isso é modificação e não extensão. Isto esperamos que fique igual. Toda pizza passa pelo mesmo processo.

7 Outro princípio Identifique os aspectos de seu sistema que variam e separe-os dos que permanecem iguais. Padrões de Projeto - Factory Method Por que esse princípio é tão importante? Resp.: assim conseguimos isolar as partes do código que sofrem mudanças. Identificando o que varia, podemos buscar algum padrão que resolva o problema eliminando ou diminuindo a ocorrência de mudanças no código.

8 Aplicando o princípio... Pizza orderPizza(String type){ Pizza pizza;
pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } 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. Padrões de Projeto - Factory Method SimplePizzaFactory Essa classe encarregada de criar objetos sempre é chamada de Factory. if(type.equals("Moussarela")) pizza = new Moussarela(); else if(type.equals("Pepperoni")) pizza = new Pepperoni(); else if(type.equals(“Margherita") pizza = new Margherita(); Não resolve 100% dos nossos problemas mas estamos no caminho certo... Aumentamos, um pouquinho, a coesão do sistema.

9 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; } Padrões de Projeto - Factory Method Até aqui, só orderPizza utilizaria o método createPizza. Mas se criássemos uma outras classes PizzaShopMenu e HomeDelivery, elas reutilizariam esse código. Quando houvesse alteração, apenas um lugar seria mudado, ao invés de três. 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.

10 agora PizzaStore tem uma referência a SimplePizzaFactory
PizzaStore recebe a fábrica no construtor 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; O método orderPizza agora usa a fábrica para criar suas pizzas Padrões de Projeto - Factory Method Note que agora não existe mais o modificador new. As instanciações concretas ficam na fábrica.

11 The Simple Factory Padrões de Projeto - Factory Method

12 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 Padrões de Projeto - Factory Method A Factory, por si só, não é um padrão de projeto. É um programming idiom. Eu diria que seria uma boa prática.

13 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. Padrões de Projeto - Factory Method Uma solução seria utilizar fábricas diferentes... RioTintoFactory Massa fina, molho temperado e pouco queijo. JoaoPessoaFactory

14 Problems? RioTintoFactory rtFactory = new RioTintoFactory();
PizzaStore rtStore = new PizzaStore(rtFactory); rtStore.order("Moussarela"); JoaoPessoaFactory jpFactory = new JoaoPessoaFactory(); PizzaStore jpStore = new PizzaStore(jpFactory); jpStore.order("Moussarela"); 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). Padrões de Projeto - Factory Method

15 Como contornar este problema?
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. Padrões de Projeto - Factory Method

16 The Method Factory Pattern
agora PizzaStore é abstrata createPizza volta para PizzaStore, ao invés de estar num objeto de fábrica 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); As novas lojas não interferem no restante do processo. Perceba que PizzaStore é fechado para modificação mas flexível. Por que? Padrões de Projeto - Factory Method Não é mais preciso alterar PizzaStore para criar novas Pizzas ou novas lojas. Ao criar novas lojas, por herança, cada uma decide como cada pizza deve ser criada mas não interferem no restante do processo. 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.

17 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 Padrões de Projeto - Factory Method Perceba que PizzaStore nunca é mudada e nós conseguimos adicionar novas maneiras de criar pizzas, isso é flexibilidade e extensibilidade. Na nossa logística da PizzaSapore, poderíamos entregar todo o restante do código compilado (Sapore.jar), e garantir que o business model das pizzarias Sapore é seguido em todas as franquias. Cada franquia somente herdaria PizzaStore e forneceria a implementação do método de fábrica, createPizza. Exemplo de produto concreto

18 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. Padrões de Projeto - Factory Method Vocês precisam entender essa definição. Se tiverem dúvidas me avisem.

19 Terminologia e Estrutura
Padrões de Projeto - Factory Method Product  pizza ConcreteProduct  diferentes tipos de pizza Creator  loja abstrata/ pizzaStore ConcreteCreator  diferentes tipos de loja para cada região

20 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 temperado Tempo de forno: 7 Temperatura: 550ºC Manjericão, massa fina, pouco queijo, molho temperado Tempo de forno: 10 Temperatura: 500ºC Pepperoni Pepperoni, muito queijo, molho apimentado Moussarela Muito queijo Pouco queijo Tempo de forno: 8 Temperatura: 450ºC Padrões de Projeto - Factory Method

21 Padrões de Projeto - Factory Method

22 Referências [1] O cenário de pizzarias é abordado no capítulo 4 do livro “Padrões de Projeto – Use a Cabeça!” Padrões de Projeto - Factory Method


Carregar ppt "Aula 6 – Padrão Factory Method"

Apresentações semelhantes


Anúncios Google