[Dúvida] Comunicação entre Camadas MVC!

Olá, pessoal do GUJ!

Venho eu mais uma vez com minhas dúvidas!

Bom, tenho uma classe DAO mais ou menos assim:

public class UsuarioDAO {

   public List<Usuario> readByExample(Usuario usuario) {
      List<Usuario> usuarios = new ArrayList<Usuario>();
      // faz toda a codificação para pegar dados.
      return usuarios;
   }
}

De acordo com minha arquitetura definida, eu optei por não instanciar classes Pojo em classes View.
Há algum modo de eu passar essa lista de usuários para a View sem a necessidade de instanciar um objeto Usuario lá?

Pensei na idéia de usar várias listas para os vários atributos desse Pojo, jogando tudo em um Mapa, mas fica inviável.

Eis o código que pensei:

public class UsuarioAction {
   
   public Map<String, Object> readByExample(Map<String, Object> input) {
      
      Usuario usuario = new Usuario();
      usuario.setUsuario(input.get("usuario"));
      usuario.setSenha(input.get("senha"));

      List<String> usuarios = new ArrayList<String>();
      List<String> senhas   = new ArrayList<String>();

      for (Usuario u : UsuarioDAO.getInstance().readByExample(usuario)) {
      
         usuarios.add(u.getUsuario());
         senhas.add(u.getSenha());
      }

      Map<String, Object> output = new HashMap<String, Object>();
      output.put("usuarios", usuarios);
      output.put("senhas", senhas);

      return output;
   }
}

No caso, estou sincronizando as duas Lists na View, mas o problema é que é MUITO inviável essa prática!

Alguma idéia para solucionar essa minha dúvida?

Agradeço a todos!

Forte abraço! :smiley:

Nao ha problema na View conhecer o model, afinal ela é a representacao visual do model e vlce nao pode representar o que voce nao conhece. O contrario é que é problema.

Olá, Yvga!

Sim, eu entendo que não há problema.
O meu intuito é tornar a minha View o mais desacoplada possível das outras camadas, por isso a intenção!

Supondo que este seja o padrão definido, alguma dica para refatorar e melhorar o código acima?

[]'s

Utilize o padrão factory, dessa forma você tira a responsabilidade da criação dos objetos da visão.

Olá, Lauden!

Algum link onde eu possa me orientar sobre este padrão Factory?

[]'s

Aqui na seção de artigos tem um extremamente bom e completo sobre o assunto, o ponto é que com esse padrão você leva a lógica de criação dos objetos para outra classe sendo essa classe a tua " fábrica de objetos ", contendo métodos como getNovoCliente() por exemplo.

Pode explicar por que vc acha essa prática inviável?

flws

Olá, fantomas!

Bom, aqui vão alguns motivos pelos quais não considero viável a prática que estou tomando:

  1. Perco performance, pois estou fazendo computação desnecessária;
  2. A minha tipagem é perdida também, pois a relação entre ID, usuário e senha é quebrada totalmente;
  3. Em alguns momentos, eu deverei fazer cast, perdendo segurança assim;
  4. Imagina só um Pojo com 50 atributos… Jogar 50 Lists num Map e jogar pra View… Não seria muito viável, entende?

Postem suas opiniões, por favor!

Abraço a todos!

Uma maneira que encontrei para evitar de criar muitos sacos de dados muito especializados que ficam trafegando entre o banco e view é fazer um uso maior de composição e agregação dos objetos. Evita ficar usando maps.

Uma coisa que não entendi é por que você está retirando os dados que vêm do model e colocando em outra lista?

No lugar de mandar duas List pra tela, eu mande uma List

Agora, sobre instanciar objetos na view, neste teu exemplo você também não precisaria. Por que não mandar as strings de usuário e senha diretamente para o model, como parâmetros? (Ironicamente é justamente o caso contrário do que eu disse acima)

Olá, Bruno!

É isso mesmo que quero evitar. Não quero que a classe Pojo Usuário se comunique com a classe View UsuarioManagerForm, por exemplo!

Então, estou procurando soluções para burlar isso!

Uma idéia que me deram foi usar uma lista de Mapas!

Por exemplo, eu pego um objeto Usuário, pego seus atributos e jogo em um mapa. Após isso, jogo esse Mapa numa Lista de Mapas!
Confuso, não? rs

Algo mais ou menos assim:

public class UsuarioAction {  
     
   public List<Map<String, Object>> readByExample(Map<String, Object> input) {  
        
      Usuario usuario = new Usuario();  
      usuario.setUsuario(input.get("usuario"));  
      usuario.setSenha(input.get("senha"));  
  
      List<Map<String, Object>> output = new List<Map<String, Object>>();
  
      for (Usuario u : UsuarioDAO.getInstance().readByExample(usuario)) {  
        
         Map<String, Object> dados = new HashMap<String, Object>();
         dados.put("usuario", u.getUsuario());
         dados.put("senha", u.getSenha());

         output.put(output.size(), dados);  
      }  
  
      return output;  
   }  
}  

O que acham dessa alternativa? Válida?

[]'s

Acho que você procurando fio de cabelo em casca de ovos. Não tem muito sentido a View e o Controller não saberem sobre o Model.

Mandando objetos usuário e senha para a view você já esta se acoplando de alguma forma ao model. A única maneira que vejo deste desacoplamento ser vantajoso é se você for tirar os usuários e senhas de outros objetos que não sejam usuário. Talvez este não seja um exemplo muito bom de um caso vantajoso, mas outros podem ser. Mesmo assim a view seria genérica demais.

O próximo passo dessa generalização seria mandar uma matriz de Strings para a tela (O que faz sentido em numa taglib genérica de dados tabulares).

[quote=Nicolas Fernandes]Olá, pessoal do GUJ!

Venho eu mais uma vez com minhas dúvidas!

Bom, tenho uma classe DAO mais ou menos assim:

public class UsuarioDAO {

   public List<Usuario> readByExample(Usuario usuario) {
      List<Usuario> usuarios = new ArrayList<Usuario>();
      // faz toda a codificação para pegar dados.
      return usuarios;
   }
}

De acordo com minha arquitetura definida, eu optei por não instanciar classes Pojo em classes View.
[/quote]

É otimo que vc não instancie nada na página jsp. No seu exemplo vc precisa mostrar os nomes e senhas
dos usuários (se entendi bem) e vc faz um for sobre os usuários. Isso é errado. Isso não é OO.

Depois que vc objetem a lista dos usuários vc passa a lista toda para a view e a view se vira
para a renderizar (usando tags especificas e EL).

Esta é a prática comum. Vc não manda tipos primitivos (string, double,integer,etc… ) vc manda objetos completos
que leu do seu DAO ou criou na sua action.

Reitero tudo isso que o YvGa disse.

Como o colega disse acima, não procure pelo em ovo, não há problema nenhum do controler e view conhecerem o Model e não vejo motivo plausível da view ser tão independente assim.

É… No fim, estou mesmo procurando pêlo em ovo!! hehe

Mas obrigado, pessoal!

Pude tirar algumas idéias deste tópico.

Agradeço a participação de todos!

Abraços!