Dúvida Sobre OO - Regra de Negocios e DAO

Pessoal, estou iniciando um sistema em Java, e estou com uma dúvida em relação a OO:

– Eu estou fazendo um módulo de Usuarios que acessarao o sistema, entao obvimente, preciso de um método autentica() (usei esse nome no meu projeto). Esse método compara o que foi digitado pelo usuário, com o devido registro no BD. Agora vem a dúvida, eu devo criar esse método dentro do meu UsuarioDao (Persistencia), ou dentro de Usuario (Entidade) ?

Na segunda opção, eu devo dar um import do meu DAO para poder listar os usuarios no BD, e entao fazer a devida comparação dentro da Entidade ? O que seria correto fazer, levando em conta que os dois jeitos acho que funcionariam, porem apenas um seria o correto dentro do contexto da OO.

OBS: estou desenvolvendo para plataforma WEB, usando MVC.

Obrigado

Diego,

Embora fuja um pouco do conceito de OO, o mais comum é você criar o método no seu DAO. Suas entidades serão simples POJOs.

Certo. Mas isso nao atrapalha a manutencao do sistema futuramente, se outro programador entra na equipe por exemplo ? Isso esta de acordo com os padrões do Java ?

Isso é padrão, principalmente quando uso algum framework de persistência como Hibernate ou JPA, pode ficar tranquilo :slight_smile:

Na minha opinião vc deveria fazer assim…

no sua entidade vc pode ter um método simples de autenticar… algo assim

[code]public class User {
private String senha;
private String login;
//…

public boolean autenticar(String senha) {
    return (this.senha == senha); //Ps.: se sua senha tiver MD5, converta pra MD5 aqui dentro e faça o teste de igualdade
}

}[/code]

o seu DAO fica sem nada do tipo como autenticar…

vc pode ter 1 controlador, outro, que faça esse tipo de coisa pra vc, sem ser no DAO… algo assim

public class AutenticadorDeLogin { public static User autenticar(String login, String senha) { User usuario = DaoUser.getInstance().findByLogin(login); if (usuario != null && usuario.autenticar(senha)) return usuario else throw new LoginException("Login ou senha não conferem"); } }

Agora no seu sistema, vc pode ao receber login e senha fazer algo como

[code]

try {
User usuario = AutenticadorDeLogin.autenticar(login,senha);
} catch(LoginException le) {
System.out.println(ex.getMessage());
}[/code]

eu prefiro manter minhas entidades com um pouco de logica, nada de mais, só o que for inerente a ela propria… e não colocaria logica no DAO não, so ferramenta de buscas de entidades e essas coisas

Talvez sua dúvida não seja especificamente de OO e sim de separar as responsabilidades de cada camada na sua aplicação (separation of concerns). As duas soluções acimas vão funcionar, mas qual será mais fácil de manter?
Eu usaria uma outra maneira de fazer isso (nao estou pensando apenas em autenticação, estou generalizando um pouco mais)
Criaria um serviço de usuario que teria um metodo de autenticar, que usaria um repositorio para acessar os dados do banco e validar caso for necessário, porque se achou registro no banco é porque o usuario existe.

Agora justificando porque nao usaria as outras soluções acima, lembrando que estou generalizando um pouco mais:

  1. Validar no DAO
    Acho que a camada DAO fica sendo pra infra-estrutura, aí que entra o “separation of concerns”. Imagina colocar regra de autenticação lá. voce com um OracleDAO, se trocar o banco vai ter que reescrever a validação identica?

  2. Autenticar pela classe “AutenticadorDeLogin” acima
    Métodos estáticos “soa” uma programação procedural. Voce acaba caindo num padrão do tipo Active Record ( http://martinfowler.com/eaaCatalog/activeRecord.html ). Você no fundo acaba tendo dores de cabeça pra testar esses métodos. Tamos num projeto em que começamos com Active Record e tiramos tudo, e nisso foi bastante código jogado fora e ganhamos facilidades de teste

Bom essa é minha opinião, pode ter coisas nessas duas maneiras de fazer que não vi :slight_smile:

Abraços

[quote=diegocharles]Pessoal, estou iniciando um sistema em Java, e estou com uma dúvida em relação a OO:

– Eu estou fazendo um módulo de Usuarios que acessarao o sistema, entao obvimente, preciso de um método autentica() (usei esse nome no meu projeto). Esse método compara o que foi digitado pelo usuário, com o devido registro no BD. Agora vem a dúvida, eu devo criar esse método dentro do meu UsuarioDao (Persistencia), ou dentro de Usuario (Entidade) ?
[/quote]

Nenhum dos dois. “obviamente preciso de um método autentica” é otima.

Autenticação é um processo. Vc precisa das credenciais do usuário ( nome, password ) e precisa que alguem faça a verificação.
Esse alguem não pode ser o usuário. O usuário não pode se auto-autenticar. Isso é absurdo.
A autenticação não é um processo ligado a banco de dados. (pode ser, e no seu caso é, mas no caso geral não é) , logo o DAO não tem nada a haver com isso.

O que vc precisa é de um serviço de autenticação que verifica que o usuário tem aquelas credenciais.
Como o serviço faz essa identificação é um detalhe de implementação, mas o serviço tem que ser algo separado do usuario e do dao.


interface AutenticationService {

       public void autenticate(String userName, Set<Credencials> credentials) throws AutenticationException;
}


class DB AutenticationService implements AutenticationService  {

  public void autenticate(String userName, Set<Credencials> credentials) throws AutenticationException{

         // procura no banco pelo usario com o nome userName
         // se não existe lance UserNotFoundAutenticationException que é subclasse de AutenticationException
         // para cada credenctial : 

         // se a credencial é uma Credential De Password verifica se o usuário tem aquela password e ela é válida ( não experirou, etc..) 
        // se não foi encontrado lance CredentialNotFoundAutenticationException , se é invalida InvalidCredentialAutenticationException
        
       // se tudo correu bem simplesmente não faça nada

 }
}

Se a autenticação é correta o método simplesmente passa. Se não ele lança exceção.

É comum que este método retorna o usuário do banco, ma isso deve ser feito com cuidado.
Apenas se o usuário é válido ele pode ser autenticado.
Outras operações durante a autenticação consistem em autorgar permissões ao usuário conforme a autenticação.
Por exemplo se o usuário forneceu a super-password ele tem permissões especiais. Se forneceu apenas a password normal tem permissões limitadas. Se forneceu as duas, tem todas as pemrissões