Estrutura de uma aplicação MVC

Esqueci de comentar:

Nada do que esta sendo discutido aqui tem alguma coisa relacionada a MVC.

Só uma coisa YvGa, em nenhum momento em que critiquei o uso dos DAOs eu quis dizer q em seu lugar se deveria colocar suas queries no controller.
Em minhas primeiras respostas à este post eu sugeri o uso das NamedQueries como substituto aos DAOs. Com NamedQueries ao invés disso:

public class UserController {

  private final EntityManager em;

  public List<User> users() {
    return em.createQuery("select u from User u").getResultList();
  }

}

Vc faz isso:

public class UserController {

  private final EntityManager em;

  public List<User> users() {
    return em.createNamedQuery(User.ALL).getResultList();
  }

}

Afinal, isso é só uma maneira mais genérica de se escrever isso:

public class UserController {

  private final UserDAO userDAO;

  public List<User> users() {
    return userDAO.findUsers();
  }

}

As NamedQueries do JPA são declaradas nas entidades assim como vc faria com classes de modelo de frameworks como Rails.

@Entity
@Table(name = "USER")
@NamedQueries({
  @NamedQuery(name = User.ALL, query = "select u from User u", resultClass = User.class)
})
public class User implements Serializable {

  public static final String ALL = "User.all";
// ... o resto do código da entidade.

Como vc pode ver, não há necessidade é se escrever uma classe a mais e manter um arquivo a mais, e ainda se transforma o EntityManager em um DAO genérico não causando, assim, nenhum tipo
de desordem nos seus controllers.

Vlw pela contribuição galera, só assim diminuo minhas dúvidas.

Uma pergunta, por exemplo, o usuário quer alterar a senha, de qual objeto seria essa responsabilidade?
Usuario ou UsuarioService?

[quote=j0nny]Vlw pela contribuição galera, só assim diminuo minhas dúvidas.

Uma pergunta, por exemplo, o usuário quer alterar a senha, de qual objeto seria essa responsabilidade?
Usuario ou UsuarioService?[/quote]

Usuario.

A classe que contem os dados deve ser sempre a responsavel por qualquer alteracao neles.

[quote=YvGa][quote=j0nny]Vlw pela contribuição galera, só assim diminuo minhas dúvidas.

Uma pergunta, por exemplo, o usuário quer alterar a senha, de qual objeto seria essa responsabilidade?
Usuario ou UsuarioService?[/quote]

Usuario.

A classe que contem os dados deve ser sempre a responsavel por qualquer alteracao neles.[/quote]

Mesmo que minha classe entidade tenha que fazer acesso a um DAO?

[quote=j0nny][quote=YvGa][quote=j0nny]Vlw pela contribuição galera, só assim diminuo minhas dúvidas.

Uma pergunta, por exemplo, o usuário quer alterar a senha, de qual objeto seria essa responsabilidade?
Usuario ou UsuarioService?[/quote]

Usuario.

A classe que contem os dados deve ser sempre a responsavel por qualquer alteracao neles.[/quote]

Mesmo que minha classe entidade tenha que fazer acesso a um DAO?[/quote]

Eu nao gosto de acesso a dados diretamente dentro das entidades, a nao ser que haja um framework que cuide disso de forma transparente, como o grails e o rails.

Mas mesmo no caso de voce precisar acessar um dao, ainda assim a regra de alteracao da senha deve ficar na classe Usuario, nesse caso. A chamada ao DAO pode ficar fora, num service ou no proprio controller se for um caso simples como esse.

A principal preocupacao a se ter em mente é que voce nao esta lidando com dados, mas com objetos, e o que voce vai salvar é o estado do objeto. Nesse caso voce vai salvar o estado de um usuario com uma nova senha e nao a nova senha do usuario x.

Entao nesse caso, voce vai escrever a regra de mudanca de senha na sua propria classe Usuario, seja ela qual for. Do seu controller voce vai chamar o metodo alterarSenha, passando a informacao da view e o que mais for necessario para o objeto usuario. Veja que o controller nao faz ideia de qual seja essa regra, ele so sabe qual metodo chamar e o que passar como parametro, la dentro ele nao tenha ideia do que acontece. Se algo der errado o metodo levanta uma exceção que será tratada pelo controller.


  //em algum metodo do controller
try{
  usuario.alterarSenha(senhaAtual, novaSenha); //nesse metodo está a regra de como a senha deve ser alterada
  usuarioDao.guardar(usuario); // ou como prefere o dev.rafael em.save(usuario);
}
catch(Exception e){
   //trata a excecao e exibe ao usuario
}

Um service não se encaixa, na minha opiniao, nesse exemplo pela simplicidade dele. Adicionar um service é só por mais uma camada sem que ela traga nenhum ganho.
Um service entraria na jogada caso voce precisasse, por exemplo, enviar um email a alguem cada vez que houvesse alguma alteracao de senha. Note que esta seria uma regra de sua aplicacao, por tanto ela nao deve estar no controller, que é responsavel apenas por transportar os dados da view ao core da sua aplicacao, por tanto nao deve ser responsavel por executar nenhuma regra dela. Mas tambem a sua entidade usuario não deve ter a responsabilidade de enviar um email a ninguem, porque nesse caso ela estaria fazendo mais do que o necessario, alem de estar, desnecessariamente se acoplando a um sistema complexo de envio de mensagens.

Aí entraria em cena um service, que seria chamado pelo controller e faria alem daquilo que o controller faz no exemplo acima, tambem mandaria o email pra quem tivesse que mandar.

[quote=YvGa][quote=j0nny][quote=YvGa][quote=j0nny]Vlw pela contribuição galera, só assim diminuo minhas dúvidas.

Uma pergunta, por exemplo, o usuário quer alterar a senha, de qual objeto seria essa responsabilidade?
Usuario ou UsuarioService?[/quote]

Usuario.

A classe que contem os dados deve ser sempre a responsavel por qualquer alteracao neles.[/quote]

Mesmo que minha classe entidade tenha que fazer acesso a um DAO?[/quote]

Eu nao gosto de acesso a dados diretamente dentro das entidades, a nao ser que haja um framework que cuide disso de forma transparente, como o grails e o rails.

Mas mesmo no caso de voce precisar acessar um dao, ainda assim a regra de alteracao da senha deve ficar na classe Usuario, nesse caso. A chamada ao DAO pode ficar fora, num service ou no proprio controller se for um caso simples como esse.

A principal preocupacao a se ter em mente é que voce nao esta lidando com dados, mas com objetos, e o que voce vai salvar é o estado do objeto. Nesse caso voce vai salvar o estado de um usuario com uma nova senha e nao a nova senha do usuario x.

Entao nesse caso, voce vai escrever a regra de mudanca de senha na sua propria classe Usuario, seja ela qual for. Do seu controller voce vai chamar o metodo alterarSenha, passando a informacao da view e o que mais for necessario para o objeto usuario. Veja que o controller nao faz ideia de qual seja essa regra, ele so sabe qual metodo chamar e o que passar como parametro, la dentro ele nao tenha ideia do que acontece. Se algo der errado o metodo levanta uma exceção que será tratada pelo controller.


  //em algum metodo do controller
try{
  usuario.alterarSenha(senhaAtual, novaSenha); //nesse metodo está a regra de como a senha deve ser alterada
  usuarioDao.guardar(usuario); // ou como prefere o dev.rafael em.save(usuario);
}
catch(Exception e){
   //trata a excecao e exibe ao usuario
}

Um service não se encaixa, na minha opiniao, nesse exemplo pela simplicidade dele. Adicionar um service é só por mais uma camada sem que ela traga nenhum ganho.
Um service entraria na jogada caso voce precisasse, por exemplo, enviar um email a alguem cada vez que houvesse alguma alteracao de senha. Note que esta seria uma regra de sua aplicacao, por tanto ela nao deve estar no controller, que é responsavel apenas por transportar os dados da view ao core da sua aplicacao, por tanto nao deve ser responsavel por executar nenhuma regra dela. Mas tambem a sua entidade usuario não deve ter a responsabilidade de enviar um email a ninguem, porque nesse caso ela estaria fazendo mais do que o necessario, alem de estar, desnecessariamente se acoplando a um sistema complexo de envio de mensagens.

Aí entraria em cena um service, que seria chamado pelo controller e faria alem daquilo que o controller faz no exemplo acima, tambem mandaria o email pra quem tivesse que mandar.[/quote]

Cara, que explicação clara :lol:
Deu pra entender legal agora, a entidade cuida dela mesma, e regras de aplicação envolvendo a entidade, no service, certo?

Vamos lá…só pra finaizar minha participação no tópico. E eu não baixei o nível, não entendi seu comentário.

Em casos de aplicações SIMPLES, seja lá o que isso quer dizer, adote a prática do programador poliglota, não pense que Java é a solução para tudo, por que ele não é. Se vocẽ precisa construir uma aplicação simṕles busque linguagens simples e seja feliz.

Agora se vc adotou Java, crie sua arquitetura e design com um mínimo de preocupação com o futuro.

[quote=dev.rafael]
Com relação ao decorator, na boa, ou vc não sabe inglês eu vc simplesmente não entendeu o q o cara escreveu.

In object-oriented programming, the decorator pattern is a design pattern that allows new/additional behaviour to be added to an
existing object dynamically.

A chave está em “new/adicional behavior”. Como encapsular um DAO genérico (EntityManager) em um outro DAO genérico pode ser um
Decorator se vc não está adicionando nenhum comportamento a este? Como vc está criando um decorator se vc está mudando a interface
da classe decorada?[/quote]

Com relação ao meu inglês, isso lhe diz respeito, então vou desconsiderar esse seu comentário (embora tenha fluência na lingua).

O pattern só para que vc entenda melhor, um EntityMamanger possui operações BÁSICAS para realização de CRUD, porém no meu sistema eu preciso adicionar consultas voltadas ao negócio, no caso estou “adicionando” funcionalidades mais específicas.

[]'s