Olá pessoal. [desculpem pelos problemas de acentuacao no texto, mas ainda nao configurei meu teclado…]
Gostaria de discutir com os colegas uma solucao que adotei para meu pequeno projeto.
Neste projeto estou usando apenas JSF2 para camada de apresentacao, Hibernate - JPA, e Apache Shiro para a seguranca.
Bom, mesmo com poucos frameworks, desenhei a aplicacao em camadas separando a camada de apresentacao (junto com controllers no caso do JSF) e a camada de services.
Para manter uma boa pratica de desenho, os services estao orientados a interface (nao sei se posso escrever assim mesmo - orientado a interfaces).
Possuo a seguinte estrutura:
pacote.services.[nome referente ao negocio].api -> possui as interfaces
pacote.services.[nome referente ao negocio].impl -> possui as implementacoes
Como eu nao quis usar o spring, criei uma classe que me devolve uma instancia de um service dada uma interface enviada como parametro.
Este “ServiceFactory” entao possui (por enquanto) um metodo estático que retorna a classe concreta para a interface.
Desta forma, em meus backing beans, utilizo apenas a interface gerando um menor acoplamento.
Não utilizei DI pois é realmente um projeto pequeno e não acredito que há necessidade.
Outro fato é que tentei buscar um pouco de “convention over configuration”.
Observando o código abaixo e o cenário descrito gostaria de saber se acham muito ruim esta abordagem, o que poderia melhorar e enfim, no final das contas me ajudar a saber se estou tomando o caminho certo. :lol:
package br.com.xxx.service.support;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import br.com.xxx.service.support.exception.ServiceFactoryException;
/**
* Provides a factory to obtain service implementations by convention over configuration.
* @author adolfo
*/
public class ServiceFactory {
/**
* Retrieves an implementation instance of the interface sent by type parameter.
* @param <T> - Interface definition
* @param type - Interface class definition
* @return - implementation of the type
* @throws ServiceFactoryException
*/
@SuppressWarnings("unchecked")
public static <T> T getService(Class<? extends T> type) throws ServiceFactoryException {
// retrieving the implementation service name.
String[] qualifiedName = type.getName().split("\\.");
List<String> qualifiedNameList = Arrays.asList(qualifiedName);
int classNameIndex = qualifiedNameList.size() - 1;
int switchIndex = qualifiedNameList.size() - 2;
String className = qualifiedNameList.get(classNameIndex);
String newName = className.substring(1).concat("Impl");
qualifiedNameList.set(switchIndex, "impl");
qualifiedNameList.set(classNameIndex, newName);
String qualifiedNameString = StringUtils.join(qualifiedName, ".");
// building the implementation class qualified name.
try {
return (T) Class.forName(qualifiedNameString).newInstance();
} catch (Exception e) {
throw new ServiceFactoryException(e);
}
}
}
Através da classe acima posso “chamar” um service conforme o código abaixo:
...
IProductsService service = ServiceFactory.getService(IProductsService.class);
System.out.println(service.getProductName());
...
Obrigado.