Padrão de Construção Factory Method Equipe: Danielle, Gerson e Samuel "Definir uma interface para criar um objeto mas deixar que subclasses decidam que classe instanciar. Factory Method permite que uma classe delegue a responsabilidade de instanciamento às subclasses." [GoF] 1. Introdução A maneira padrão de construir objetos em Java é através de construtores. 2. Problema O acesso a um objeto concreto será através da interface conhecida através de sua superclasse, mas cliente também não quer (ou não pode) saber qual implementação concreta está usando. 3. Padrões de Construção • Builder: obtém informação necessária em passos antes de requisitar a construção de um objeto • Factory Method: adia a decisão sobre qual classe concreta instanciar • Abstract Factory: constuir uma família de objetos que compartilham um "tema" em comum • Prototype: especificar a criação de um objeto a partir de um exemplo fornecido • Memento: reconstruir um objeto a partir de uma versão que contém apenas seu estado interno 4. Factory Method É possível criar um objeto sem ter conhecimento algum de sua classe concreta? • Esse conhecimento deve estar em alguma parte do sistema, mas não precisa estar no cliente • FactoryMethod define uma interface comum para criar objetos • O objeto específico é determinado nas diferentes implementações dessa interface Factory methods são métodos estáticos que retornam uma instância de uma classe. Exemplo:Calendar.getInstance public class ComplexNumber { /** * Static factory method returns an object of this class. */ public static ComplexNumber valueOf(float aReal, float aImaginary) { return new ComplexNumber(aReal, aImaginary); } //private constructor prevents subclassing private ComplexNumber (float aReal, float aImaginary) { fReal = aReal; fImaginary = aImaginary; } private float fReal; private float fImaginary; } 5. Estrutura do Padrão 5. Estrutura do Padrão 5. Estrutura do Padrão 5. Estrutura do Padrão 6. Implementação /*** MazeGame sem factory method.*/ public class MazeGame { // Create the maze. public Maze createMaze() { Maze maze = new Maze(); Room r1 = new Room(1); Room r2 = new Room(2); Door door = new Door(r1, r2); maze.addRoom(r1); maze.addRoom(r2); r1.setSide(MazeGame.North, new Wall()); r1.setSide(MazeGame.East, door); r1.setSide(MazeGame.South, new Wall()); r1.setSide(MazeGame.West, new Wall()); r2.setSide(MazeGame.North, new Wall()); r2.setSide(MazeGame.East, new Wall()); r2.setSide(MazeGame.South, new Wall()); r2.setSide(MazeGame.West, door); return maze; } E se quiséssemos uma DoorWithLock ou um WallWithHiddenDoor? Teríamos que fazer mudanças significativas na classe já que as instanciações estão sendo feitas usando o operador new dentro do createMaze(). 6. Implementação /*** MazeGame com factory method.*/ public class MazeGame { public Maze makeMaze() { return new Maze(); } public Room makeRoom(int n) { return new Room(n); } public Wall makeWall() { return new Wall(); } public Door makeDoor(Room r1, Room r2){ return new Door(r1, r2); } public Maze createMaze() { Maze maze = makeMaze(); Room r1 = makeRoom(1); Room r2 = makeRoom(2); Door door = makeDoor(r1, r2); maze.addRoom(r1); maze.addRoom(r2); r1.setSide(MazeGame.North, makeWall()); r1.setSide(MazeGame.East, door); r1.setSide(MazeGame.South, makeWall()); r1.setSide(MazeGame.West, makeWall()); r2.setSide(MazeGame.North, makeWall()); r2.setSide(MazeGame.East, makeWall()); r2.setSide(MazeGame.South, makeWall()); r2.setSide(MazeGame.West, door); return maze;}} public class EnchantedMazeGame extends MazeGame { public Room makeRoom(int n) { return new EnchantedRoom(n); } public Wall makeWall() { return new EnchantedWall(); } public Door makeDoor(Room r1, Room r2) { return new EnchantedDoor(r1, r2); } } Dessa forma, nós podemos fazer createMaze() um pouco mais complexa, mas muito mais flexível. O método createMaze() é herdado em EhchantedMazeGame e pode ser usado para criar mazes normais ou enchanted mazes sem mudança. 7. Vantagens • Criação de objetos é desacoplada do conhecimento do tipo concreto do objeto • Conecta hierarquias de class 8. Desvantagens • Ainda é preciso saber a classe concreta do criador de instâncias (pode-se usar uma classe Factory, com método estático e parametrizado que chame diretamente o Factory Method): Perguntas? Design Patterns Parte 1 • É uma interface para instanciação de objetos que mantém isoladas as classes concretas usadas da requisição da criação destes objetos. • Separa assim: – uma “família” de classes dotadas da mesma interface (“produtos”); e – uma classe (“fábrica”) que possui um método especial (o factory method) que cria tais objetos. Referências Bibliográficas [1] ALEXANDER, C., ISHIKAWA, S., SILVERSTEIN, M., JACOBSON, M., FIKSDAHL-KING, I., ANGEL, S. "A Pattern Language". New York, NY (USA): Oxford University Press, 1977. [2] COPLIEN, J. O. "Software Patterns". New York, NY (USA): SIGS Books, 1996. [3] GAMMA, E., HELM, R., JOHNSON, R., VLISSIDES, J. "Design Patterns: Elements of Reusable Object-Oriented Software". Reading, MA: Addison Wesley, 1995. [4] GEARY, D. ”A look at the Composite pattern". IN JavaWorld, setembro, 2002. [http://www.javaworld.com/javaworld/jw-09-2002/jw-0913designpatterns_p.html] Design Patterns Parte 2 Padrão Factory Method (Fábrica) • Permite que uma classe genérica (escrita para ser reusada) instancie outras classes sem que seja dependente de tais classes, isto é, sem que faça menção explícita a essas. A classe genérica se mantém independente das classes que instancia através da delegação para um outro objeto da escolha de qual classe instanciar e somente refere-se ao objeto então criado através de uma interface comum. • Permite criar objetos desejados utilizando métodos que retornam os objetos. Padrão Factory Method – Geral Padrão Factory Method – Exemplo Classificação e Catálogo de Design Patterns Classificações de Patterns • Podem ser classificados quanto ao: – Escopo: • Classes; • Objetos. – Quanto ao seu propósito: • Criacional; • Estrutural; • Comportamental. Organização de Design Patterns • Quanto ao escopo: – classes: patterns tratam do relacionamento entre classes e subclasses; – objetos: patterns tratam relacionamentos entre objetos e por isso podem ser alterados em tempo de execução. – Ex: Um padrão estrutural de classe utiliza herança para compor as classes, enquanto um padrão estrutural de objeto descreve como estes devem ser agrupados. Organização de Design Patterns • Quanto ao seu propósito: – Criacional; – Estrutural; – Comportamental. Organização de Design Patterns • Quanto ao seu propósito: – Criacional: • Diz respeito ao processo de criação de um objeto; • Ex1: Builder - separa a construção de um objeto complexo de sua representação, desta maneira um mesmo processo pode ser utilizado para criar diferentes representações. – Estrutural; – Comportamental. Organização de Design Patterns • Quanto ao seu propósito: – Criacional; – Estrutural: • Diz respeito a composição de objetos e classes; • Ex: Composite - Compõe objetos em árvores de agregação (relacionamento parte-todo). O Composite permite que objetos agregados sejam tratados como um único objeto. – Comportamental. Organização de Design Patterns • Quanto ao seu propósito: – Criacional; – Estrutural; – Comportamental: • Caracteriza o modo como classes e objetos interagem e compartilham responsabilidades. • Ex: Iterator - Provê um modo de acesso a elementos de um agregado de objetos, seqüencialmente, sem exposição de estruturas internas. Organização dos Design Patterns Escopo Class Object Criação Factory Method Abstract Factory Builder Prototype Singleton Propósito Estrutural Adapter (classe) Adapter (object) Bridge Composite Decorator Façade Flyweight Proxy Funcionamento Interpreter Template Method Chain of Responsibility Command Iterator Mediator Memento Observer State Strategy Visitor Catálogo de Design Patterns • Abstract Factory: Provê uma interface para criação de famílias de objetos relacionados ou interdependentes. Remove a dependência entre o cliente, que usa os objetos, e a classe dos objetos produzidos. • Adapter: Converte a interface de uma classe em outra, esperada pelo cliente. O Adapter permite que classes que antes não poderiam trabalhar juntas, por incompatibilidade de interfaces, possam agora fazê-lo. • Bridge: Separa uma abstração de sua implementação, de modo que ambas possam variar independentemente. • Builder: Provê uma interface genérica para a construção incremental de agregações. Um Builder esconde os detalhes de como os componentes são criados, representados e compostos. Catálogo de Design Patterns • Chain of Responsibility: Encadeia os objetos receptores e transporta a mensagem através da corrente até que um dos objetos a responda. Assim, separa (provê loose coupling) objetos transmissores dos receptores, dando a chance de mais de um objeto poder tratar a mensagem. • Command: Encapsula uma mensagem como um objeto, de modo que se possa parametrizar clientes com diferentes mensagens. Separa, então, o criador da mensagem do executor da mesma. • Composite: Compõe objetos em árvores de agregação (relacionamento parte-todo). O Composite permite que objetos agregados sejam tratados como um único objeto. • Decorator: Anexa responsabilidades adicionais a um objeto dinâmicamente. Provê uma alternativa flexível para extensão de funcionalidade, sem ter que usar Herança. Catálogo de Design Patterns • Facade: Provê uma interface unificada para um conjunto de interfaces em um subsistema. O Facade define uma interface alto nível para facilitar o uso deste subsistema. • Factory Method: Define uma interface para criação de um objeto, permitindo que as suas subclasses decidam qual classe instanciar. O Factory Method deixa a responsabilidade de instanciação para as subclasses. • Flyweight: Usa o compartilamento para dar suporte eficiente a um grande número de objetos com alto nível de granularidade. • Interpreter: Usado para definição de linguagem. Define representações para gramáticas e abstrações para análise sintática. • Iterator: Provê um modo de acesso a elementos de um agregado de objetos, sequencialmente, sem exposição de estruturas internas. Catálogo de Design Patterns • Mediator: Desacopla e gerencia as colaborações entre um grupo de objetos. Define um objeto que encapsula as interações dentre desse grupo. • Memento: Captura e externaliza o estado interno de um objeto (captura um "snapshot"). O Memento não viola o encapsulamento. • Observer: Provê sincronização, coordenação e consistência entre objetos relacionados. • Prototype: Especifica os tipos de objetos a serem criados num sistema, usando uma instância protótipo. Cria novos objetos copiando este protótipo. • Proxy: Provê Design para um controlador de acesso a um objeto. • Singleton: Assegura que uma classe tenha apenas uma instância e provê um ponto global de acesso a ela. Catálogo de Design Patterns • State: Deixa um objeto mudar seu comportamento quando seu estado interno muda, mudando, efetivamente, a classe do objeto. • Strategy: Define uma família de algoritmos, encapsula cada um deles, e torna a escolha de qual usar flexível. O Strategy desacopla os algoritmos dos clientes que os usa. • Template Method: Define o esqueleto de um algoritmo em uma operação. O Template Method permite que subclasses componham o algoritmo e tenham a possibilidade de redefinir certos passos a serem tomados no processo, sem contudo mudá-lo. • Visitor: Representa uma operação a ser realizada sobre elementos da estrutura de um objeto. O Visitor permite que se crie um nova operação sem que se mude a classe dos elementos sobre as quais ela opera.