Modelagem, duvidas!

7 respostas
J

Ola pesoal, estou com uma duvida de principiante, já q o sou…
é o seguinte:quero criar um sistema de inclusão, alteração e deleção de usuarios.Com quantas classe eu ficaria??Estava pensando em somente ter uma classe usuario com esses métodos inser,altera,exclui.É correto pensar assim, ou existe outra maneira de implementar o design de sistema???
alguem tem uma eplicacao um pouco mais clara e objetiva de como criar classe a partir de uj requirements??

Obrigado desde já

7 Respostas

douglasfs

“juliosp”:
Ola pesoal, estou com uma duvida de principiante, já q o sou…
é o seguinte:quero criar um sistema de inclusão, alteração e deleção de usuarios.Com quantas classe eu ficaria??Estava pensando em somente ter uma classe usuario com esses métodos inser,altera,exclui.É correto pensar assim, ou existe outra maneira de implementar o design de sistema???
alguem tem uma eplicacao um pouco mais clara e objetiva de como criar classe a partir de uj requirements??

Obrigado desde já

Não querendo te complicar, mas já complicando :lol: a maneira que eu implemento o acesso a banco de dados é através de patterns, que basicamente são soluções para resolver um determinado tipo de problema, atualmente estou implementando a camada de acesso a dados do meu projeto de conclusão de curso na faculdade utilizando o pattern DAO - Data Access Object (http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html), este pattern separa a camada de negócios da camanda de acesso a banco de dados, no caso esse pattern ensina a implementar classes que sejam independente de um banco de dados especifico, se você conhece herança e polimorfismo você não terá dificuldades em aprende-lo.

Basicamente do basicamente o ideal é implementar assim :

// Classe com atributos e métodos de acesso/lógica do negócio, sem nenhum sql
public class Usuario {
   private String nome;
   private String senha;
   public Usuario(String pnome, String psenha) {
      nome = pnome;
      senha = psenha;
   }

   public String getNome() {
      return nome;
   }

   public String getSenha() {
      return senha;
   }

   public void autentica() {
      // blablabla
   }

}
// classe de acesso a banco de dados
public class UsuarioDAO {
   public int inserirUsuario(Usuario usuario) {
      insert into tabela(nome,senha) values (usuario.getNome(),usuario.getSenha());
      // mais código ...
   }

   public boolean deletarUsuario(Usuario usuario) {
      // mais código
   }

}
public class Teste {
   public static void main(String args[]) {
      UsuarioDAO userdb = new UsuarioDAO();
      Usuario user = new Usuario("douglas","minhasenha");
      userdb.inserirUsuario(user);
   }
}

Caso você conheça bem herança e polimorfismo, eu posso te fornecer alguns trechos de código do meu projeto que inclui a independencia de banco de dados.

Caso tenha alguma dúvida é só postar, é que eu não tenho uma boa didática :lol:

I

Douglas,

Aproveitando sua explicação nesta mensagem gostaria de tirar uma dúvida. Para métodos que buscam um usuário ou uma coleção de usuários por algum critério, você colocaria estes métodos na própria classe Usuário ou criaria outra classe ?

Valeu,

Ivan.

A

Eu também estava com estas dúvidas e vi que alguns implementam do jeito que o douglas falou e outros criando uma única classe com os métodos de acesso a banco sendo static. Acho q as duas opções são válidas.

Também estou com a mesma dúvida do Ivan.

Dêem uma olhada no tópico Modelagem e Implementação em Java Avançado que também tem algumas discussões sobre o tema.

douglasfs

“Ivan Martins”:
Douglas,

Aproveitando sua explicação nesta mensagem gostaria de tirar uma dúvida. Para métodos que buscam um usuário ou uma coleção de usuários por algum critério, você colocaria estes métodos na própria classe Usuário ou criaria outra classe ?

Valeu,

Ivan.

Ainda se baseando no pattern DAO, eu implementei assim :

Os métodos para busca eu os coloquei na classe de acesso a banco de dados ficaria assim :

// classe de acesso a banco de dados 
public class UsuarioDAO { 
   public int inserirUsuario(Usuario usuario) { 
      insert into tabela(nome,senha) values (usuario.getNome(),usuario.getSenha()); 
      // mais código ... 
   } 

   public boolean deletarUsuario(Usuario usuario) { 
      // mais código 
   } 

} 

// Busca uma coleção de usuários, como retorno eu utilizo o java.util.ArrayList, poderia ser o java.util.Collection  

public ArrayList findUserByName(Usuario criteria) {
      ArrayList listaUsuarios = new ArrayList();
      // codigo para efetuar o select, vou por em alto nivel
      select nome, senha from tabela where nome=criteria.getNome();
     // executa o método next do ResultSet
     // primeiro verifico se eu tenho alguma ocorrência
     if (rs.next()) {
        do {
           Usuario  usuario = new Usuario(rs.getString("nome"),rs.getString("senha"));
            listaUsuarios.add(usuario);
        }
        while(rs.next());
     }
     else
        return null;    

      return listaUsuarios;

}
// Busca somente um usuário
public Usuario findUserByID(Usuario criteria) {
       Usuario usuario = null;      
      // codigo para efetuar o select, vou por em alto nivel
      select nome, senha from tabela where id=criteria.getID();
     // executa o método next do ResultSet
     // primeiro verifico se eu tenho alguma ocorrência
     if (rs.next()) {
          usuario = new Usuario(rs.getString("nome"),rs.getString("senha"));
          return usuario;
     }
     else
        return null;   

}
// Exemplo utilizando a busca por nome (retorna uma coleção):
   int i;
   Usuario usuario = null;
   UsuarioDAO usuarioDB = new UsuarioDAO();
   Usuario criterio = new Usuario();
   criterio.setNome("DOUGLAS");
   // busca no banco de dados todas as ocorrências que contenham o nome DOUGLAS
   ArrayList lista = usuarioDB.findUserByName(criterio);
   if (lista != null) {
      for (i=0;i<lista.size();i++) {
         usuario = (Usuario) lista.get(i);   
         System.out.println(usuario.getNome());
      }   
   }
// agora eu busco só um usuário
   Usuario usuario = null;
   UsuarioDAO usuarioDB = new UsuarioDAO();
   Usuario criterio = new Usuario();
   criterio.setID(20);
   usuario = usuarioDB.findUserByID(criterio);
   if (usuario == null) {
      // não encontrou o usuário;
   }
   else
      // encontrou o usuário
claudio

Opa Galera, perai...

Lembrando que um dos motivos da utilização de linguagens orientadas a objetos eh a reutilizacao de codigo, logo nao se deve confundir as coisas.

Uma coisa sao as suas classes de negocio (JavaBeans) e outra coisa eh persistencia.

Se vc poe informacoes de persistencia diretamente no seu bean vc esta matando a sua reutilização, no exemplo que vcs estao usando, a classe usuario, quantos sistemas diferente poderao ser feitos se utilizando dessa classe?? Muitos, mas cada um em um BANCO/TABELA diferentes ;)

A Melhor maneira eh sem duvida a utilizacao de DAO como ja disse o douglasfs, onde TODA informacao referente a persistencia (banco/tabela/ mapeamento objeto-relacional) sera armazenada.

E apenas comentando o codigo enviado pelo douglasfs.

1) Nunca utilize classes de collections como retorno, sempre use as Interfaces, isso possibilita que vc altere o tipo de collection sem se preoculpar com quem usa, a assinatura do metodo ficaria assim:

public Collection findUserByName(Usuario criteria) {  ...

2) Nunca retorne null caso nada tenha vindo, crie uma Exception de Negocio, como UsuarioNotFoundException e sempre que nada for encontrado lance a Exception, o modelo de Exception foi criado para esses casos tb, e a migracao para algum tipo de framework distribuido (ejb por exemplo) ficaria mais facil uma fez que eles trabalham dessa forma (FinderException), o codigo ficara assim:

public Collection findUserByName(Usuario criteria) throws UserNotFoundException { 
      ArrayList listaUsuarios = new ArrayList(); 
      // codigo para efetuar o select, vou por em alto nivel 
      select nome, senha from tabela where nome=criteria.getNome(); 
     // executa o método next do ResultSet 
     // primeiro verifico se eu tenho alguma ocorrência 
     if (rs.next()) { 
        do { 
           Usuario  usuario = new Usuario(rs.getString("nome"),rs.getString("senha")); 
            listaUsuarios.add(usuario); 
        } 
        while(rs.next()); 
     } 
     else 
        throw new UserNotFoundException("Nenhum usuario encontrado!");

      return listaUsuarios; 

}

Agora uma frescura minha ;), eu costumo pedir aos alunos para tentar deixar o codigo o mais claro possivel uma vez que varias pessoas na empresa talvez leiam ele, entao eu evito if com do while, eu faria assim:

public Collection findUserByName(Usuario criteria) throws UserNotFoundException { 
      ArrayList listaUsuarios = new ArrayList(); 
      // codigo para efetuar o select, vou por em alto nivel 
      select nome, senha from tabela where nome=criteria.getNome(); 
     // executa o método next do ResultSet 
     // primeiro verifico se eu tenho alguma ocorrência 

     while(rs.next()){
           Usuario  usuario = new Usuario(rs.getString("nome"),rs.getString("senha")); 
            listaUsuarios.add(usuario); 
        } 
         
        if (usuario.size() == 0){
                throw new UserNotFoundException("Nenhum usuario encontrado!");
        }

      return listaUsuarios; 

}

Abraco,

douglasfs
  1. Nunca utilize classes de collections como retorno, sempre use as Interfaces, isso possibilita que vc altere o tipo de collection sem se preoculpar com quem usa, a assinatura do metodo ficaria assim:
public Collection findUserByName(Usuario criteria) {  ...

Perfeito, no projeto que eu estou fazendo eu utilizo a interface Collection como retorno (no pattern DAO ele utiliza essa interface como exemplo), geralmente eu faço um casting para o ArrayList (poderia converte-lo para um iterator).

  1. Nunca retorne null caso nada tenha vindo, crie uma Exception de Negocio, como UsuarioNotFoundException e sempre que nada for encontrado lance a Exception, o modelo de Exception foi criado para esses casos tb, e a migracao para algum tipo de framework distribuido (ejb por exemplo) ficaria mais facil uma fez que eles trabalham dessa forma (FinderException), o codigo ficara assim:

Você tem razão caso haja uma migração, qualquer exemplo de EJB (como o findByPrimaryKey) ele dispara uma exceção caso ele não encontre nada.

Agora uma frescura minha ;), eu costumo pedir aos alunos para tentar deixar o codigo o mais claro possivel uma vez que varias pessoas na empresa talvez leiam ele, entao eu evito if com do while, eu faria assim:

Hehehe isso é mania (já estou perdendo) de programador C/Perl :lol: , sem dúvida verificando o tamanho do ArrayList para verificar se a lista está vazia deixa o código mais claro, só modificando uma linha no seu código para deixa-lo ainda mais claro :lol: .

public Collection findUserByName(Usuario criteria) throws UserNotFoundException { 
      ArrayList listaUsuarios = new ArrayList(); 
      // codigo para efetuar o select, vou por em alto nivel 
      select nome, senha from tabela where nome=criteria.getNome(); 
     // executa o método next do ResultSet 
     // primeiro verifico se eu tenho alguma ocorrência 

     while(rs.next()){ 
           Usuario  usuario = new Usuario(rs.getString("nome"),rs.getString("senha")); 
            listaUsuarios.add(usuario); 
        } 

        // opa  :) você colocou por engano usuario.size() ao invés de listaUsuarios.size()          
        //if (usuario.size() == 0){ 
        // testa se a lista está vazia, tanto faz size() == 0 ou isEmpty
          if (listaUsuarios.isEmpty())
                throw new UserNotFoundException("Nenhum usuario encontrado!"); 
        } 

      return listaUsuarios; 

}

Só colocando uma obsevação, caso alguém for efetuar o teste com as modificações efetuadas pelo Claudio o exemplo ficará mais ou menos assim (é bem básico):

int i; 
   Usuario usuario = null; 
   ArrayList lista = null;
   UsuarioDAO usuarioDB = new UsuarioDAO();
   Usuario criterio = new Usuario(); 
   criterio.setNome("DOUGLAS"); 
try {
      // busca no banco de dados todas as ocorrências que contenham o    nome DOUGLAS
   lista = (ArrayList) usuarioDB.findUserByName(criterio); 
   for (i=0;i<lista.size();i++) { 
      usuario = (Usuario) lista.get(i);    
      System.out.println(usuario.getNome()); 
   }       
}
catch (UserNotFoundException unfe) {
   System.out.println("Usuário não encontrado " + unfe.getMessage());
   unfe.printStackTrace();
}
claudio

Show!

Abraco,

Criado 14 de abril de 2003
Ultima resposta 15 de abr. de 2003
Respostas 7
Participantes 5