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 8. Desvantagens • 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-0913-designpatterns_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
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.