Abstract Factory

Objetivo

Também chamado de

Resumo

Exemplo: look-and-feel de GUIs

O padrão Abstract Factory

Quando usar o padrão Abstract Factory?

Estrutura genérica

Participantes

Colaborações entre objetos

Consequências do uso do padrão Abstract Factory

Considerações de implementação

Exemplo de código: criação de labirintos

public interface FactoryDeLabirintoIF {
    public LabirintoIF criaLabirinto();
    public SalaIF criaSala(int númeroDaSala);
    public ParedeIF criaParede() {
    public PortaIF criaPorta(SalaIF sala1, SalaIF sala2) {
}

class FactoryDeLabirinto
            implements FactoryDeLabirintoIF {
    // Factory Methods
    // Tem default para as Factory Methods
    public LabirintoIF criaLabirinto() {
        return new Labirinto();
    }

    public SalaIF criaSala(int númeroDaSala) {
        return new sala(númeroDaSala);
    }

    public ParedeIF criaParede() {
        return new Parede();
    }

    public PortaIF criaPorta(SalaIF sala1, SalaIF sala2) {
        return new Porta(sala1, sala2);
    }
}
class Jogo implements JogoIF {
    // Observe que essa função não tem new: ela usa
    // uma Abstract Factory recebido como parâmetro
    // Esta é a *única* diferença com relação à versão original
    // Observe que criaUmLabirinto recebe um factory como parâmetro;
    // Em vez disso, poderíamos usar o padrão Singleton
    public LabirintoIF criaUmLabirinto(FactoryDeLabirintoIF factory) {
        LabirintoIF umLabirinto = factory.criaLabirinto();
        SalaIF sala1 = factory.criaSala(1);
        SalaIF sala2 = factory.criaSala(2);
        PortaIF aPorta = factory.criaPorta(sala1, sala2);

        umLabirinto.adicionaSala(sala1);
        umLabirinto.adicionaSala(sala2);

        sala1.setVizinho(norte, factory.criaParede());
        sala1.setVizinho(leste, aPorta);
        sala1.setVizinho(sul, factory.criaParede());
        sala1.setVizinho(oeste, factory.criaParede());

        sala2.setVizinho(norte, factory.criaParede());
        sala2.setVizinho(leste, factory.criaParede());
        sala2.setVizinho(sul, factory.criaParede());
        sala2.setVizinho(oeste, aPorta);

        return umLabirinto;
    }
}
class FactoryDeLabirintoEncantado extends FactoryDeLabirinto {
    public SalaIF criaSala(int númeroDaSala) {
        return new salaEncantada(númeroDaSala, jogaEncantamento());
    }
    public PortaIF criaPorta(SalaIF sala1, SalaIF sala2) {
        return new portaPrecisandoDeEncantamento(sala1, sala2);
    }
    protected EncantamentoIF jogaEncantamento() {
        ...
    }
}
class FactoryDeLabirintoPerigoso extends FactoryDeLabirinto {
    public ParedeIF criaParede() {
        return new paredeDestruível();
    }
    public SalaIF criaSala(int númeroDaSala) {
        return new salaComBomba(númeroDaSala);
    }
}
    JogoIF umJogo = new Jogo();
    FactoryDeLabirintoPerigoso factory =
            new FactoryDeLabirintoPerigoso();
    jogo.criaLabirinto(factory);

Perguntas finais para discussão

pat-9 programa anterior próxima