Fala ae Pessoal!
Estou estudando arquitetura e estou tentando entender melhor alguns patterns. Bom, eu queria uma opinião apara saber se a minha implementação de teste do Command, com Abstract Factory e as implementações destas seriam favoráveis.
Defini uma classe comum a todos os comandos (por enquanto apenas NovoPedido e ExcluirPedido):
public abstract class BaseCommand {
public abstract BaseCommand executar();
public static String className(Class<?> classe){
return classe.getSimpleName();
}
}
E as duas classes que representam um comando:
public class NovoPedido extends BaseCommand {
@Override
public BaseCommand executar() {
System.out.println("Executando comando: Criar um Pedido");
return null;
}
}
public class ExcluirPedido extends BaseCommand {
@Override
public BaseCommand executar() {
System.out.println("Executando o comando: Excluir um Pedido");
return null;
}
}
Criei então duas implementações diferentes de uma factory para os comandos: Uma implementação por reflection e outra hardcoded.
A interface da factory:
public interface CommandFactory {
public BaseCommand create(String command);
}
E as implementações:
public class DynamicCommandFactory implements CommandFactory {
private Properties classesDeComando = new Properties();
public DynamicCommandFactory() {
try {
FileInputStream inputStream = new FileInputStream("commands.properties");
classesDeComando.load(inputStream);
inputStream.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
@Override
public BaseCommand create(String command) {
BaseCommand baseCommand = null;
String nomeDaClasse = classesDeComando.getProperty(command);
try {
Class classe = Class.forName(nomeDaClasse);
baseCommand = (BaseCommand) classe.newInstance();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return baseCommand;
}
}
public class StaticCommandFactory implements CommandFactory {
@Override
public BaseCommand create(String command) {
BaseCommand baseCommand = null;
if(command.equals("NovoPedido")){
baseCommand = new NovoPedido();
} else if(command.equals("ExcluirPedido")){
baseCommand = new ExcluirPedido();
}
return baseCommand;
}
}
Sendo assim, preferi decidir por reflection para habilitar qual destas duas usar, então criei um implementação de CommandFactory:
public class CommandFactoryImpl implements CommandFactory {
private CommandFactory commandFactoryInstance = null;
public CommandFactoryImpl(){
Properties factoryName = new Properties();
try {
FileInputStream inputStream = new FileInputStream("config.properties");
factoryName.load(inputStream);
String factory = factoryName.getProperty("Factory");
Class<?> classe = Class.forName(factory);
commandFactoryInstance = (CommandFactory) classe.newInstance();
inputStream.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
@Override
public BaseCommand create(String command) {
return commandFactoryInstance.create(command);
}
}
E no meu aplicativo de testes resolvi injetar a implementação da factory ao invés de instancia-la:
public class Aplicativo {
private CommandFactory commandFactory = null;
@Inject
public Aplicativo(CommandFactoryImpl commandFactoryImpl) {
this.commandFactory = commandFactoryImpl;
}
public CommandFactory getCommandFactory(){
return this.commandFactory;
}
public static void main(String[] args) {
//apenas para resolver o problema de injeção de dependência
Aplicativo aplicativo = new Aplicativo(new CommandFactoryImpl());
CommandFactory command = aplicativo.getCommandFactory();
BaseCommand baseCommand1 = command.create(BaseCommand.className(NovoPedido.class));
novoPedido(baseCommand1);
BaseCommand baseCommand2 = command.create(BaseCommand.className(ExcluirPedido.class));
excluirPedido(baseCommand2);
}
//simula uma ação de novoPedido
private static void novoPedido(BaseCommand baseCommand){
baseCommand.executar();
}
//simula uma ação de excluirPedido
private static void excluirPedido(BaseCommand baseCommand){
baseCommand.executar();
}
}
Gostaria de saber se está implementação seria válida em um cenário real e o que eu poderia melhor nesta situação. Valeu!