Horda e Aliança
Quando escrevi meu primeiro artigo, “O Padrão State e o Druida de World of Warcraft”, tive a ideia de criar vários artigos explicando os padrões de projeto utilizando exemplos do jogo WoW. Então, espere mais artigos. Desta vez, vamos explorar o padrão criacional Abstract Factory.
O que é o Abstract Factory?
A principal função deste padrão é fornecer uma interface para criar famílias de objetos relacionados ou dependentes, sem especificar suas classes concretas. Ele busca desacoplar o código cliente das classes que realmente produzem os objetos, permitindo maior flexibilidade e escalabilidade. Complexo, né? Vamos para um exemplo simples para maior entendimento.
Exemplo Simples: Uma Fábrica de Comida
Imagine uma fábrica que pode preparar dois tipos de culinária: japonesa e italiana. Cada culinária oferece diferentes pratos, mas todos pertencem a um grupo específico.
Com o padrão Abstract Factory, você simplesmente escolhe o tipo de comida (japonesa ou italiana), e a fábrica cuida de todo o processo, entregando os pratos dessa família sem que você precise conhecer os detalhes internos da preparação.
Um Exemplo Complexo: Horda e Aliança no WoW
No jogo World of Warcraft, existem duas facções rivais: Horda e Aliança (FOR THE HORDE!). Cada facção possui diferentes raças, e cada raça pode pertencer a uma classe específica.
Ao utilizar o padrão Abstract Factory, podemos criar uma estrutura onde o jogador primeiro escolhe a facção, depois a raça e por fim a classe do personagem, sem se preocupar com os detalhes técnicos.
Estrutura do Código:
Interfaces
- Classe: Define um contrato para todas as classes de personagens.
- Raça: Define um contrato para todas as raças de personagens.
- FabricaFaccoes: Define métodos para criar objetos de raça e classe.
Implementações
- Guerreiro e Paladino: Implementam a interface
Classe
. - Orc e Humano: Implementam a interface
Raça
.
Fábricas Concretas
- FabricaHorda: Cria objetos da facção Horda (Orc e Guerreiro).
- FabricaAlianca: Cria objetos da facção Aliança (Humano e Paladino).
Implementação Detalhada
Interface Classe
package com.cesar.classe;
public interface Classe {
String mostrarClasse();
}
Implementações:
package com.cesar.classe;
public class Guerreiro implements Classe {
@Override
public String mostrarClasse() {
return "Guerreiro";
}
}
public class Paladino implements Classe {
@Override
public String mostrarClasse() {
return "Paladino";
}
}
Interface Raça
package com.cesar.raca;
public interface Raça {
String mostrarRaça();
}
Implementações:
package com.cesar.raca;
public class Orc implements Raça {
@Override
public String mostrarRaça() {
return "Orc";
}
}
public class Humano implements Raça {
@Override
public String mostrarRaça() {
return "Humano";
}
}
Interface FabricaFaccoes
package com.cesar.fabrica;
import com.cesar.classe.Classe;
import com.cesar.raca.Raca;
public interface FabricaFaccoes {
Raca escolherRaca();
Classe escolherClasse();
}
Fábricas Concretas
package com.cesar.fabrica;
import com.cesar.classe.Classe;
import com.cesar.classe.Guerreiro;
import com.cesar.raca.Orc;
import com.cesar.raca.Raca;
public class FabricaHorda implements FabricaFaccoes {
@Override
public Raca escolherRaca() {
return new Orc();
}
@Override
public Classe escolherClasse() {
return new Guerreiro();
}
}
package com.cesar.fabrica;
import com.cesar.classe.Classe;
import com.cesar.classe.Paladino;
import com.cesar.raca.Humano;
import com.cesar.raca.Raca;
public class FabricaAlianca implements FabricaFaccoes {
@Override
public Raca escolherRaca() {
return new Humano();
}
@Override
public Classe escolherClasse() {
return new Paladino();
}
}
Classe Principal
package com.cesar;
import com.cesar.classe.Classe;
import com.cesar.fabrica.FabricaAlianca;
import com.cesar.fabrica.FabricaHorda;
import com.cesar.raca.Raca;
import com.cesar.fabrica.FabricaFaccoes;
public class Main {
public static void main(String[] args) {
FabricaFaccoes fabricaHorda = new FabricaHorda();
Raca racaHorda = fabricaHorda.escolherRaca();
Classe classeHorda = fabricaHorda.escolherClasse();
System.out.println("Você escolheu a facção Horda da raça " + racaHorda.mostrarRaça() + " da classe " + classeHorda.mostrarClasse() + ".");
FabricaFaccoes fabricaAlianca = new FabricaAlianca();
Raca racaAlianca = fabricaAlianca.escolherRaca();
Classe classeAlianca = fabricaAlianca.escolherClasse();
System.out.println("Você escolheu a facção Aliança da raça " + racaAlianca.mostrarRaça() + " da classe " + classeAlianca.mostrarClasse() + ".");
}
}
Saída Esperada
Você escolheu a facção Horda da raça Orc da classe Guerreiro.
Você escolheu a facção Aliança da raça Humano da classe Paladino.
Código disponível em:
Conclusão:
O padrão Abstract Factory é utilizado para:
- Definir uma interface para criação de famílias de objetos relacionados.
- Desacoplar o código cliente da lógica de criação dos objetos concretos.
Neste exemplo, as fábricas FabricaHorda
e FabricaAlianca
criam personagens específicos para cada facção sem expor diretamente os tipos concretos de classes (Orc
, Humano
, Guerreiro
, Paladino
).
Deixe um comentário