Padrões de Projeto de Software Abstract Factory Paulo Gomide Departamento de Ciência da Computação Universidade de Itaúna
Sumary Abstract Factory Definição, Motivação e Aplicabilidade Estrutura, Elementos do Padrão e Colaborações Consequências Consequências Alternativas e Dicas de Implementação Código de Exemplo Padrões Relacionados
Abstract Factory Definição Provê uma interface para criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas Também conhecido como Kit
Motivação para o Padrão Motivação Considere a implementação de um toolkit que disponibilize controles que funcionem em diferentes interfaces gráficas. Para ser portável, a aplicação não deveria se referir diretamente aos elementos (widgets) de um padrão de controle particular. Solução: WidgetFactory - interface para criar cada tipo básico de GUI; Uma classe abstrata para cada tipo de widget; Subclasse concreta para cada padrão distinto; Clientes usam a WidgetFactory e não têm conhecimento das classes concretas que implementam widgets particulares; WidgetFactory assegura consistência entre classes concretas.
Estrutura do Problema Específico
Aplicabilidade Requisitos para se Aplicar o Padrão O uso do padrão Abstract Factory é indicado quando: O sistema deve ser independente de como seus produtos são criados, compostos e representados O sistema deve ser configurado com uma ou com múltiplas famílias de produtos Uma família de objetos de produtos relacionados é projetada para ser usada de forma conjunta e você deva garantir esta restrição Você quer prover uma biblioteca de classes de produtos e quer revelar apenas suas interfaces e não suas implementações
Estrutura do Problema Geral
Cliente Participantes do Padrão Implementa a interface AbstractProduct; Usa somente as interfaces AbstractFactory e AbstractProduct. AbstractFactory Declara uma interface para a criação de objetos-produto abstratos; Ex.: WidgetFactory. ConcreteFactory Implementa as operações para criar objetos-produto concretos; Ex.: MotifWidgetFactory e QTWidgetFactory.
Participantes AbstractProduct Declara uma interface para um tipo de objeto-produto; Ex.: Window e ScrollBar. ConcreteProduct Define um objeto-produto a ser criado pela sua fábrica concreta correspondente; Implementa a interface AbstractProduct; Ex.: MotifWindow e MotifScrollBar
Colaborações Principais Contribuição do Padrão AbstractFactory delega a criação de objetos-produto a suas subclasses ConcreteFactory; Normalmente uma única instância da classe ConcreteFactory é criada; Para criar objetos-produto diferentes, os clientes devem usar uma fábrica concreta diferente.
Conseqüências Vantagens 1. Isola classes concretas: Uma AbstractFactory encapsula a criação de objetos de produtos; Isola clientes das classes de implementação; O cliente manipula instâncias através de suas interfaces abstratas. 2. Facilita o câmbio de famílias de produtos: A ConcreteFactory só aparece em um lugar: onde ela é instanciada; Uma mudança numa única linha de código pode ser suficiente para mudar a ConcreteFactory que a aplicação usa; A família inteira de produtos muda de uma vez.
Vantagens Conseqüências 1. Promove a consistência entre produtos: Produtos de uma determinada família devem funcionar conjuntamente e não misturados com produtos de outra família; O padrão permite implementar esta restrição com facilidade. Desvantagens 1. Dificulta o suporte a novos tipos de produtos O motivo é que a AbstractFactory fixa o conjunto de produtos que podem ser criados; Dar suporte a mais produtos força a extensão da interface da factory o que envolve mudanças na AbstractFactory e em todas suas subclasses ConcreteFactory;
Alternativas e Dicas de Implementação Implementação do Padrão 1. Fábricas geralmente são melhor implementadas como Singletons; 2. AbstractFactory apenas declara a interface para a criação de produtos; 3. Deve uma fábrica concreta (ou uma para cada famíla de produtos); 4. Definir fábricas extensíveis.
Código de Exemplo
Código de Exemplo
Código de Exemplo Para implementar um labirinto que contenha cômodos encantados, basta fazer subclasse de MazeFactory:
Exemplo Para criar um labirinto que contenha cômodos encantados, basta chamar CreateMaze com um EnchantedMazeFactory:
Exemplo Para implementar um labirinto no qual um cômodo ou uma porta pode ter uma bomba, basta fazer subclasses novamente, sobrescrevendo os dois métodos:
Exemplo Para criar um labirinto que contenha bombas, basta chamar CreateMaze com um BombedMazeFactory
Exemplo
Padrões Relacionados Factory Method As principais semelhanças são: Em vez do cliente chamar um método de criação (Factory Method), ele possui um objeto (Abstract Factory) e usa este objeto para chamar os métodos de criação. Factory Method quer que você seja diferente (via herança) para criar objetos diferentes, o Abstract Factory quer que você tenha algo diferente
Obrigado pela atenção! Dúvidas?