Olá pessoal relendo alguns posts do GUJ, como este http://www.guj.com.br/posts/list/15/60916.java
e outros do blog da caelum como este http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto entre outros lugares, comecei a me questionar sobre a maneira como tenho arquiteturado minhas aplicações WEB.
Atualmente quando vou fazer um CRUD, faço da seguinte maneira, tentando ser o mais simples possível, utilizando algum framework MVC.
REQHTTP - > Action -> DAO -> SGDB
OBS
*Quando os dados chegam na Action, o POJO já vem populado pelo meu framework, como mentawai ou VRaptor.
*Minha classe Action não tem um Dao como atributo, o mesmo é instanciado dentro de cada método, isso porque utilizo um Dao generico(antes utilizava um dao para cada classe e injetava o mesmo por IoC), mas hoje prefiro a abordagem de um Dao generico, uma vez que consegui diminuir muito os numeros de .java na minha aplicação.
Quando preciso de uma funcionalidade mais “complexa”, digamos logo apos o cadastro de um usuario mandar um e-mal para o mesmo. Neste caso crio um service, como no exmplo;
[code]
class UserService {
public void save(Usuario usuario) //Usuario aqui vem populado, enviado pela action{
HibernateDao usuarioDao=new HibernateDAO<Usuario.class>();
usuarioDao.save(usuario);
sendMail();
}
private sendMail(){
//codigo para enviarEmail
}
}
As lógicos de negócio ficam nas classes de negócio como, a action servindo somente para recuperar os parametros da view e mandar para o model.
public class UserAction{
public changePassword(){
String oldPassword=input.getStringValue("oldPassword");
String newPassword=input.getStringValue("newPassword");
Usuario user=(Usuario)session.getAtributte("user");
user.changePassord(oldpassword,newpassword);
//try -catch -aqui tratando as excecoes da camada de negocio;
}
}
public class User
public changePassword(String olPassword, String newPassword){
if(senha.equals(oldPassword){
setSenha(newPassword);
}else{
throw new BussinessException("Senha invalida"); //Exceção qualquer de negocio
}
}
Uma nova abordagem que estou pensando a utilizar é a seguinte:
REQHTTP -> Action -> Modelo de Negocio > Repository(interface) > Dao> SGB
Como neste artigo http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto onde o autor fala ao inves de ter um codigo como este:
public class Logica { // extends Action? ;)
public void mostraFornecedorEContasPagas() {
Long id = request.getParameter("id");
Fornecedor f = fornecedorDAO.load(id)
List<Conta> contasPagas = contasDAO.listaContasPagasDoMes(fornecedor);
// ejeta tudo para mostrar na view. No século passado seria:
request.setAttribute("fornecedor", fornecedor);
request.setAttribute("contasPagas", contasPagas);
}
}
Pode ser substituido por
<c:forEach items="${fornecedor.ContasPagasDoMes}" var=“contas”>
<c:out value="${conta.qualquerCoisa}"/>
</c:forEach>
Onde Fornecedor tem um repository de contas!
Realmente fica bem mais OO, mais vejo algumas desvantagens, isso não seria uma violação de camada ou seja a view, está acessando diretamente o DAO, pode argumentar que repository é um conceito de negocio, tudo bem, mas no caso seria so um delegate para o DAO, isso não seria violar camadas?
Estou pensando em usar a segunda abordagem, mas antes queria ouvir sugestões. Qual estrutura geralmente vcs usam para acessar um SGDB:
REQHTTP -> Action ->Dao > SGB
REQHTTP -> Action -> Modelo de Negocio > Repository(interface) > Dao> SGB
ou ainda
req HTTP -> Action -> Modelo -> Repository -> Implementação concreta de Repository -> DAO -> Implementação concreta de UserDAO -> Banco de dados
Valeu