DESIGN PATTERN #6: FACTORY METHOD

EXEMPLO DE CÓDIGO: CRIAÇÃO DE LABIRINTOS


classe Jogo {
    // factory methods com default
    public Labirinto criaLabirinto() {
        return new Labirinto();
    }
    public Sala criaSala(int númeroDaSala) {
        return new Sala(númeroDaSala);
    }
    public Parede criaParede() {
        return new Parede();
    }
    public Porta criaPorta(Sala sala1, Sala sala2) {
        return new Porta(sala1, sala2);
    }

    // Observe que essa função não tem new: ela usa factory methods
    // Esta é a *única* diferença com relação à versão original
    public Labirinto criaLabirinto() {
        Labirinto umLabirinto = criaLabirinto();
        Sala sala1 = criaSala(1);
        Sala sala2 = criaSala(2);
        Porta aPorta = criaPorta( sala1, sala2 );

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

        sala1.setVizinho( NORTE, criaParede() );
        sala1.setVizinho( LESTE, aPorta );
        sala1.setVizinho( SUL, criaParede() );
        sala1.setVizinho( OESTE, criaParede() );

        sala2.setVizinho( NORTE, criaParede() );
        sala2.setVizinho( LESTE, criaParede() );
        sala2.setVizinho( SUL, criaParede() );
        sala2.setVizinho( OESTE, aPorta );

        return umLabirinto;
    }
}

// Um novo CriadorConcreto
class JogoPerigoso extends Jogo {
    public Parede criaParede() {
        return new ParedeDestruível();
    }
    public Sala criaSala(int númeroDaSala) {
        return new SalaComBomba(númeroDaSala);
    }
}


// Um novo CriadorConcreto
class JogoEncantado extends Jogo {
    public Sala criaSala(int númeroDaSala) {
        return new SalaEncantada(númeroDaSala, jogaEncantamento());
    }
    public Porta criaPorta(Sala sala1, Sala sala2) {
        return new PortaPrecisandoDeEncantamento(sala1, sala2);
    }
    protected Encantamento jogaEncantamento() {
        ...
    }
}