Opinião - Abordagem MVC

Olá pessoal!

Estou desenvolvendo uma aplicação seguindo arquitetura MVC e também fazendo uso do padrão DAO.
Vou relatar abaixo o fluxo da aplicação e gostaria de uma opinião se a abordagem está correta.

Suponhamos que o usuário da aplicação, acesse a opção “usuarios” do menu.

A opção “usuarios” deverá listar os usuarios cadastrados no sistema.

Para tal, tenho:

  1. Servlet ControlUsuarios - controller que recebe as requisições (ex: listar, alterar, incluir), aciona o modelo e posteriormente aciona a view necessaria.
  2. Classe Java UsuariosMD - model que é acionado pelo controller ControlUsuarios. No model tenho metodos como IncluirUsuario, ExcluirUsuario,
    ListarTodososUsuarios, InativarUsuario, entre outros. Nesse modelo valido os dados enviados pelo Controller quando houver, no caso, os dados oriundo dos
    ojbetos HttpServletRequest.
    Após a validação dos dados, o model usuario irá acionar o DAO UsuarioDAO, que contém basicamente em seu construct a criação de conexão com o banco de dados e
    e as operações para persistir os dados necessários junto ao banco de dados.
    A classe UsuarioDAO pode retornar objetos para transporte (UsuariosBean).
  3. Classe UsuariosBean - essa classe serve para gerar um objeto para servir de transporte entre as camadas. Possui setters e getters da entidade Usuario.
  4. JSP Usuarios - view acionada pelo controller ControlUsuarios, apos o controller receber a acao para listar os usuarios.

Bem, não sei se ficou muito claro, mas espero que dê para entender.

Obrigado pelas opiniões.

(Obs: como venho de outras tecnologias e estou iniciando em Java EE, optei por não utilizar frameworks ainda).

Opa. Em termos de MVC (ou melhor, daquele MVC 2) acho que não tem nada errado. Talvez fosse interessante você mudar um pouco a estrutura das classes.

Você tem um Servlet que faz tudo, mas como você vai tratar as requisições dentro dele para chamar os componentes do Model? Através de ifs? Talvez, se você fosse fazer assim, seja interessante utilizar diferentes Servlets pra diferentes ações.

Uma coisa que achei confusa é que você chamou UsuariosMD de Model e falou que o model valida os dados. Tudo bem, UsuariosMD também faz parte do Model nesse caso, mas o interessante é que a própria entidade (Usuario) se mantenha consistente (na medida do possível). UsuariosMD parece mais uma coleção de usuários, ela não deveria conhecer como funciona a entidade Usuário internamente.

Será mesmo necessário esse UsuarioBean? Você não poderia utilizar o próprio Usuario?

Outra coisa, algumas literaturas sugerem que você não acesse a camada de persistência diretamente de dentro da tua camada de domínio, o padrão Repository (Domain Driven Design) poderia evitar isso se você achar conveniente.

Abraço! Aguarde opiniões de outras pessoas. :smiley:

Oi Wagner, segue:

Opa. Em termos de MVC (ou melhor, daquele MVC 2) acho que não tem nada errado. Talvez fosse interessante você mudar um pouco a estrutura das classes.

Você tem um Servlet que faz tudo, mas como você vai tratar as requisições dentro dele para chamar os componentes do Model? Através de ifs? Talvez, se você fosse fazer assim, seja interessante utilizar diferentes Servlets pra diferentes ações.

Não terei um único servlet não, terei vários para chamar os componentes do Model e será com “ifds” mesmo.

Uma coisa que achei confusa é que você chamou UsuariosMD de Model e falou que o model valida os dados. Tudo bem, UsuariosMD também faz parte do Model nesse caso, mas o interessante é que a própria entidade (Usuario) se mantenha consistente (na medida do possível). UsuariosMD parece mais uma coleção de usuários, ela não deveria conhecer como funciona a entidade Usuário internamente.

A idéia que pensei aqui era a seguinte: UsuáriosMD é uma classe de negócios. Ela possui métodos como Login(), Logoff(), Inativar(), Ativar(). Essa classe valida os dados de acordo com minhas regras de negócio e a partir dela, caso seja necessário persistir algum dado para a base de dados, ela acessaria o UsuariosDAO.

Será mesmo necessário esse UsuarioBean? Você não poderia utilizar o próprio Usuario?

A idéia do Bean é ter um objeto serializável para ser transportados entre as camadas. Os dados recuperados da base de dados através da classe de negócios UsuariosMD são inseridos nesse UsuarioBean, para que a view faça uso dele.

Outra coisa, algumas literaturas sugerem que você não acesse a camada de persistência diretamente de dentro da tua camada de domínio, o padrão Repository (Domain Driven Design) poderia evitar isso se você achar conveniente.

Vou procurar sobre esse padrão.

Abraço! Aguarde opiniões de outras pessoas.

Obrigado pela opinião. Uma outra coisa que não deixei claro: a camada de negócio (no caso do exemplo UsuariosMD) não interage com as Servlets API. Os dados são passados para ela de modo limpo.
Da forma como imaginei: acredito que não teria problema em migrar por exemplo a aplicação para desktop. Para isso precisaria reescrever os controllers e as view. Estou correto ?

Obrigado.

[quote=ismaelrg]Oi Wagner, segue:

Opa. Em termos de MVC (ou melhor, daquele MVC 2) acho que não tem nada errado. Talvez fosse interessante você mudar um pouco a estrutura das classes.

Você tem um Servlet que faz tudo, mas como você vai tratar as requisições dentro dele para chamar os componentes do Model? Através de ifs? Talvez, se você fosse fazer assim, seja interessante utilizar diferentes Servlets pra diferentes ações.

Não terei um único servlet não, terei vários para chamar os componentes do Model e será com “ifds” mesmo.
[/quote]

Se você tiver vários servlets nem vai precisar desses ifs mesmo! O melhor é evitar cadeias longas de if.

Tipo, se nessa mesma classe você está armazenando instâncias (como comentou anteriormente com incluirUsuarios()), fazendo logon, ativando e inativando usuários e fazendo tudo, essa classe tem diversas funcionalidades. Isso não é bom (fere o princípio da responsabilidade única). Será que precisa ser tudo aí? Você não pode ter uma classe por exemplo que represente o serviço de login? Você tem uma entidade Usuario no sistema? Ela tem comportamento?

O problema de usar esse UsuarioBean é que você tem objetos anêmicos assim. Não é interessante em sistemas Orientados a Objetos manter objetos anêmicos. Não é por isso que o sistema é ruim, mas parece que nesse caso você não precisa deles. Veja aqui:

http://www.fragmental.com.br/wiki/index.php/Evitando_VOs_e_BOs

Beleza. Domain Driven Design é o nome do livro, o autor é Eric Evans. Tem um resumo gratuito do livro que inclui explicações a respeito desse padrão.

[quote=ismaelrg]
Abraço! Aguarde opiniões de outras pessoas.

Obrigado pela opinião. Uma outra coisa que não deixei claro: a camada de negócio (no caso do exemplo UsuariosMD) não interage com as Servlets API. Os dados são passados para ela de modo limpo.
Da forma como imaginei: acredito que não teria problema em migrar por exemplo a aplicação para desktop. Para isso precisaria reescrever os controllers e as view. Estou correto ?

Obrigado.[/quote]

Sim, pelo que entendi você conseguiu isolar o Model. Você realmente tem um modelo MVC (um pouco alterado porque o Model não notifica View explicitamente, mas em aplicações Web isso é comum) e poderia alterar o componente View sem muitos problemas.

Falou!

12/03/2009 10:37:01 Assunto: Re:Opinião - Abordagem MVC

ismaelrg wrote:Oi Wagner, segue:

Opa. Em termos de MVC (ou melhor, daquele MVC 2) acho que não tem nada errado. Talvez fosse interessante você mudar um pouco a estrutura das classes.

Você tem um Servlet que faz tudo, mas como você vai tratar as requisições dentro dele para chamar os componentes do Model? Através de ifs? Talvez, se você fosse fazer assim, seja interessante utilizar diferentes Servlets pra diferentes ações.
>> Não terei um único servlet não, terei vários para chamar os componentes do Model e será com "ifds" mesmo.

Se você tiver vários servlets nem vai precisar desses ifs mesmo! O melhor é evitar cadeias longas de if.
>> OK

ismaelrg wrote:
Uma coisa que achei confusa é que você chamou UsuariosMD de Model e falou que o model valida os dados. Tudo bem, UsuariosMD também faz parte do Model nesse caso, mas o interessante é que a própria entidade (Usuario) se mantenha consistente (na medida do possível). UsuariosMD parece mais uma coleção de usuários, ela não deveria conhecer como funciona a entidade Usuário internamente.
>> A idéia que pensei aqui era a seguinte: UsuáriosMD é uma classe de negócios. Ela possui métodos como Login(), Logoff(), Inativar(), Ativar(). Essa classe valida os dados de acordo com minhas regras de negócio e a partir dela, caso seja necessário persistir algum dado para a base de dados, ela acessaria o UsuariosDAO.

Tipo, se nessa mesma classe você está armazenando instâncias (como comentou anteriormente com incluirUsuarios()), fazendo logon, ativando e inativando usuários e fazendo tudo, essa classe tem diversas funcionalidades. Isso não é bom (fere o princípio da responsabilidade única). Será que precisa ser tudo aí? Você não pode ter uma classe por exemplo que represente o serviço de login? Você tem uma entidade Usuario no sistema? Ela tem comportamento?

>> Na verdade Wagner, ainda não está modelado, portanto ainda não tenho a entidade Usuario. Tudo que disse é uma hipótese para construir um sistema. No caso então, vocÊ aconselha a ter classes que representem os serviços por exemplo, como login, logout, inativar, ativar. Seria isso ?

ismaelrg wrote:
Será mesmo necessário esse UsuarioBean? Você não poderia utilizar o próprio Usuario?
>> A idéia do Bean é ter um objeto serializável para ser transportados entre as camadas. Os dados recuperados da base de dados através da classe de negócios UsuariosMD são inseridos nesse UsuarioBean, para que a view faça uso dele.

O problema de usar esse UsuarioBean é que você tem objetos anêmicos assim. Não é interessante em sistemas Orientados a Objetos manter objetos anêmicos. Não é por isso que o sistema é ruim, mas parece que nesse caso você não precisa deles. Veja aqui:

http://www.fragmental.com.br/wiki/index.php/Evitando_VOs_e_BOs

[b]>> Entendi. Achei interessante esse post, que fala extamente sobre a necessidade dos VOs (ou TO). Veja aqui: http://markmail.org/message/qwt2aogobmublgyw#query:comportamento%20entidades%20java+page:1+mid:zgrff6kd5nftlv2v+state:results

[/b]

ismaelrg wrote:
Outra coisa, algumas literaturas sugerem que você não acesse a camada de persistência diretamente de dentro da tua camada de domínio, o padrão Repository (Domain Driven Design) poderia evitar isso se você achar conveniente.
>> Vou procurar sobre esse padrão.

Beleza. Domain Driven Design é o nome do livro, o autor é Eric Evans. Tem um resumo gratuito do livro que inclui explicações a respeito desse padrão.

ismaelrg wrote:
Abraço! Aguarde opiniões de outras pessoas.

>> Obrigado pela opinião. Uma outra coisa que não deixei claro: a camada de negócio (no caso do exemplo UsuariosMD) não interage com as Servlets API. Os dados são passados para ela de modo limpo.
Da forma como imaginei: acredito que não teria problema em migrar por exemplo a aplicação para desktop. Para isso precisaria reescrever os controllers e as view. Estou correto ?

Obrigado.

Sim, pelo que entendi você conseguiu isolar o Model. Você realmente tem um modelo MVC (um pouco alterado porque o Model não notifica View explicitamente, mas em aplicações Web isso é comum) e poderia alterar o componente View sem muitos problemas.

Falou!

[b]>> Obrigado por enquanto Wagner, sua opinião está sendo de grande valia.

Dentro da arquitetura que imaginei, pelo que entendi, você sugere criar classes managers, seria isso ?!? Ex: uma classe que por exemplo implementa o serviço de login, uma que implemente o serviço de inativação do usuário, etc. Essas classes interagiriam com objetos da entidade (usuarios no caso). Seria isso ? E no caso, quando houver por exemplo a necessidade de autenticar um usuário, o controller acionaria essas classes, seria isso ?!?! E então nesse exemplo a entidade usuario não teria comportamento ???!!! [/b]

Opa.

Não sugeri objetos sem comportamento, só sugeri que tudo não se concentre num mesmo objeto. O Usuario ainda pode ter comportamentos, mas só os que ele realmente deveria ter. Será que um Usuario deve saber como se autenticar? Pense que se você deixar a autenticação por conta do Usuario, cada vez que o serviço de autenticação mudar você terá que alterar a classe Usuario. Ele pode, é verdade, saber seu password, saber se está logado, dentre outros. Mas o serviço que loga mesmo (seja acessando uma base dados, um serviço Web ou o que for) eu manteria fora. Você pode ter um LoginService que possui métodos pra logar/deslogar e recebe um Usuario como parâmetro (e aí ele pode ler os dados do usuário e logá-lo no sistema).

Quanto ao ativar/desativar Usuário, acho que depende de como você vai usar no sistema. Não sei como você pensa em fazer isso exatamente. Cada caso é um caso. :smiley:

Portanto, não é interessante criar serviços pra tudo, mas também não é interessante concentrar muitas funcionalidades numa mesma classe.

Em relação ao texto com dos DTOs, valeu, vou dar uma lida agora. :smiley:

Falou!

Opa Wagner, a discussão está me ajudando a esclarecer algumas coisas.

Bem, concordo com você sobre “Usuario” não precisar saber como se autenticar. Ficou claro essa questão de prover o serviço “Login” no caso, que faz login/logoff.
Agora, como faria no caso de um CRUD para a entidade Usuario ?!? Eu teria um outro manager para fazer isso ?!?
Aí caso positivo, seria a minha idéia do UsuarioMD, porém desmembrada. Estou correto ?

E no caso desse outro Manager, é ele quem “aciona” o UsuariosDAO para persistir os dados junto ao banco ?