Projeto de Sistemas de Software
Abstract Factory
Padrões de projeto
Bruno Freitas Gadelha
Setembro, 2008
1
Abstract Factory
Propósito
Motivação
Aplicabilidade
Estrutura
Participantes
Colaborações
Consequências
Exemplo
2
Abstract Factory
Propósito
Prover
uma interface para criar uma família
de objetos relacionados ou dependentes sem
especificar suas classes concretas
3
Abstract Factory
Motivação
Montadoras
Diferentes modelos
Diferentes acessórios
Gerador
de carros
de documentos
Diferentes documentos (textos, planilhas,
apresentacoes)
Diferentes estilos de documentos (cartas de
recomendação, curriculos, etc.)
4
Abstract Factory
Aplicabilidade
Um
sistema deve ser independente de como
seus produtos sao criados, compostos e
representados
Um sistema deve ser configurado como um
de múltiplas famílias de produtos
5
Abstract Factory
Estrutura
6
Abstract Factory
Participantes
AbstractFactory: Declara uma interface para a criação de
objetos abstratos.
ConcreteFactory: Implementa as operações que criam objetos
concretos.
AbstractProduct: Declara uma interface para um tipo de objeto.
ConcreteProduct: Define um objeto a ser criado pela fábrica
concreta correspondente e implementa a interface de
AbstractProduct.
Client: Utiliza somente as interfaces declaradas pelas classes
AbstractFactory e AbstractProduct.
7
Abstract Factory
Colaborações
Normalmente
uma única instância de uma classe
FactoryConcreta é criada em tempo de execução.
Essa FactoryConcreta cria objetos tendo uma
implementação particular. Para criar produtos
diferentes, clientes devem usar uma FactoryConcreta
diferente.
FactoryAbstrata depende de suas subclasses
FactoryConcreta para criar objetos de produtos
8
Abstract Factory
Consequências
O
padrão isola classes concretas
Uma factory encapsula a responsabilidade e o processo de
criação de objetos de produtos
Isola clientes das classes de implementação
O cliente manipula instâncias através de suas interfaces
abstratas
Facilita o câmbio de famílias de produtos
A classe da FactoryConcreta só aparece em um lugar: onde
ela é instanciada
Uma mudança numa única linha de código pode ser
suficiente para mudar a FactoryConcreta que a aplicação
usa
A família inteira de produtos muda de uma vez
9
Abstract Factory
Consequências
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
Do
lado negativo: dar suporte a novos tipos de
produtos é difícil
O motivo é que a FactoryAbstrata 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 FactoryAbstrata e em
todas suas subclasses FactoryConcreta
10
Abstract Factory
Exemplo
public abstract class Document {
protected String content;
public String getContent()
{ return content;}
public abstract String getTemplate();
public abstract String getType();
}
ProdutoAbstrato
ProdutoA1
public class SimpleLetterDocument extends Document{
public String getTemplate(){
// conteúdo para retornar o template deste tipo de documento}
public String getType(){
return “Simple Letter”; }
}
11
Abstract Factory
Exemplo
ProdutoA2
public class ProfessionalLetterDocument extends Document{
public String getTemplate(){
// conteúdo para retornar o template deste tipo de documento }
public String getType(){
return “Pro Letter”;}
}
ProdutoB1
public class SimpleSpreadSheetDocument extends
Document{
public String getTemplate(){ … }
public String getType(){
return “Simple Spreadsheet”;}
}
12
Abstract Factory
Exemplo
public class FancySpreadSheetDocument extends Document{
public String getTemplate(){…}
public String getType()
{ return “Fancy Spreadsheet”; }
}
public class LetterFactory{
public static Document getLetter(String style){
if(”simple”.equals(style))
{ return new SimpleLetterDocument(); }
if(”pro”.equals(style))
{ return new ProfessionalLetterDocument();}
else return null;
}
}
ProdutoB2
ConcreteFactory
p/ cartas
13
Abstract Factory
Exemplo
public class SpreadSheetFactory{
public static Document getSpreadSheet(String style){
if(”simple”.equals(style))
{return new SimpleSpreadSheetDocument();}
if(”fancy”.equals(style))
{return new FancyLetterDocument();}
else return null;
}
}
public class DocumentFactory{
public Document getDocument(String type, String style){
if(”letter”.equals(type))
{return LetterFactory.getLetter(style);}
if(”spreadsheet”.equals(type))
{return SpreadSheetFactory.getSpreadSheet(style);}
}
}
ConcreteFactory
p/ planilhas
AbstractFactory
14
Abstract Factory
Exemplo
Client
public class Cliente{
public static void main(String[] args){
Document letter1 = DocumentFactory.getDocument(”letter”, “simple”);
Document letter2 = DocumentFactory.getDocument(”letter”, “pro”);
Document sp1 = DocumentFactory.getDocument(”spreadsheet”, “simple”);
Document sp2 = DocumentFactory.getDocument(”spreadsheet”, “pro”);
System.out.println(letter1.getType()); // Simple Letter
System.out.println(letter2.getType()); // Pro Letter
System.out.println(sp1.getType()); // Simple Spreadsheet
System.out.println(sp2.getType()); // Fancy Spreadsheet
}
}
15