Quando usar id e quando usar objetos?

Pessoal quando eu devo usar id e quando eu devo usar objeto?
Por exemplo:

Collection getEmails(Long idUsuario) ou Collection getemails(Usuario usuario)?
Collection enviarMensagem(Lond idDestinatario, Mensagem mensagem) ou (Usuario destinatario, Mensagem mensagem)? Este último eu ainda poderia fazer diferente como enviarMensagem(Lond idDestinatario, Long idRemetente, String corpo, String assunto) ou ainda enviarMensagem(Mensagem mensagem) onde mensagem já teria tudo? enfim? São várias as formas.

Eu fico me perguntando: se temos o OOP, eu acho muito feio métodos como pesquisar(Long idTipoUsuario, Long idCidade, Char sexo, Integer idStatus) e tal.

Eu não acho tão feio. Se precisa apenas do ID, passe apenas o ID. Assim você carrega menos dado na memória. Agora, se o método precisar do Usuário, não faz sentido passar apenas o ID, porque aí o método vai ter que fazer um novo lookup de usuário.

Enfim, é caso a caso, mas passe apenas o que precisa.

[quote=mzugaib]Pessoal quando eu devo usar id e quando eu devo usar objeto?
Por exemplo:

Collection getEmails(Long idUsuario) ou Collection getemails(Usuario usuario)?
Collection enviarMensagem(Lond idDestinatario, Mensagem mensagem) ou (Usuario destinatario, Mensagem mensagem)? Este último eu ainda poderia fazer diferente como enviarMensagem(Lond idDestinatario, Long idRemetente, String corpo, String assunto) ou ainda enviarMensagem(Mensagem mensagem) onde mensagem já teria tudo? enfim? São várias as formas.

Eu fico me perguntando: se temos o OOP, eu acho muito feio métodos como pesquisar(Long idTipoUsuario, Long idCidade, Char sexo, Integer idStatus) e tal.[/quote]

Bom, a meu ver, no seu caso, o getEmails por exemplo, seria melhor passando usuario, assim como o enviarMensagem, tendo o objeto de mensagem ja com o usuario definido, isso por 2 motivos:

  • Nao expor os atributos do seu objeto e o que o torna unico (no caso o id do usuario).
  • Nao expor os atributos necessarios para executar uma operacao, quando esses atributos pertencem a uma classe.

Isso para nao criar acoplamento por parametro, ja que, imagine que vc venha a implementar alguma estratégia multi-empresa na sua aplicação, e agora, falando em mundo relacional e banco de dados, o que identifica o seu Usuario nao é apenas o Id, mas sim uma composição de id e idEmpresa. vc vai ter q sair mudando tudo na sua aplicação???

Foi so para sitar um exemplo, ja que, nesse caso, vc nao estaria complicando o modelo por estar, ao inves de esperar o id do usuario, esperar um objeto de usuario, mas sim, tornando-o mais simples.

Lembre-se, KISS sempre (Keep it simple, stupid)

VLW

Passa sempre o objeto. Não há vantagens em passar o ID. Geralmente a memória será o menor dos seus problemas, principalmente se vc organizar o programa direito.

Uma variável de referência ocupa apenas 4 bytes, o que é menor do que o seu ID, que é um long de 8. Além disso, como o pessoal falou, expor o id viola o encapsulamento e pode exigir que vc faça pesquisas desnecessárias ao banco de dados.

Num sistema ideal, o ID de um banco de dados não seria nem sequer visível para o usuário das classes de negócio. Ele ficaria encapsulado no seu framework de persistência.

Tem algum exemplo de como fazer isso?

Existem casos onde énecessário passar um identificador, por exemplo vindo de um formulário web. Por padrão, entretanto, passe objetos.

Quando você passa o ID você está deixando sua abstração vazar um detalhe de implementação.

[quote=pcalcado]Existem casos onde énecessário passar um identificador, por exemplo vindo de um formulário web. Por padrão, entretanto, passe objetos.

Quando você passa o ID você está deixando sua abstração vazar um detalhe de implementação.[/quote]

Realmente. Esta é uma situação em que fica impossível usar objeto, eu preciso de um id. Os tipos primitivos vencem, rs.

Mas fiquei curioso em saber sobre o que o Vini escreveu: Num sistema ideal, o ID de um banco de dados não seria nem sequer visível para o usuário das classes de negócio. Ele ficaria encapsulado no seu framework de persistência.

Alguma idéia?! Exemplo? Ou isso é teoria?!

[quote=mzugaib]Mas fiquei curioso em saber sobre o que o Vini escreveu: Num sistema ideal, o ID de um banco de dados não seria nem sequer visível para o usuário das classes de negócio. Ele ficaria encapsulado no seu framework de persistência.

Alguma idéia?! Exemplo? Ou isso é teoria?![/quote]

  1. Usa hibernate, ou JPA com Hibernate;
  2. Declara o seu atributo id como private e anota ele com o @Id, ou se não estiver usando JPA/Hibrenate-Annotations, no mapeamento, adiciona o atributo access=“field”, como explicado no hibernate reference, no capítulo Basic O/R mapping;
  3. Não crie os métodos get/set
  4. Crie um construtor no qual vc passa o Id.
  5. Não esquece de criar um construtor vazio para o hibernate.

Assim vc permitirá usar o Id no único momento onde ele faz sentido: na construção do objeto.

Por mim, vc não usa nem na criação do objeto.

Pelo menos, não o ID de banco de dados. Só se fizer sentido no negócio ter um ID (como no caso de uma nota fiscal). Mas aí, provavelmente também haverá gets e sets. E não será esse o campo usado para controlar o BD.

Não é teoria não. No sistema onde eu trabalho implementamos isso.
É uma maravilha. IDs são coisas das camadas mais baixas do sistema.

[quote=ViniGodoy]Por mim, vc não usa nem na criação do objeto.

Pelo menos, não o ID de banco de dados. Só se fizer sentido no negócio ter um ID (como no caso de uma nota fiscal). Mas aí, provavelmente também haverá gets e sets. E não será esse o campo usado para controlar o BD.

Não é teoria não. No sistema onde eu trabalho implementamos isso.
É uma maravilha. IDs são coisas das camadas mais baixas do sistema.[/quote]

Queria saber mais detalhes, Vini. Fiquei curioso. Vocês usam Hibernate, JPA?? Eu adoro padrões e estas solucões mais robustas. Hehehehe.

Não uso.

Na época que começamos o sistema, o Hibernate tinha sérios problemas com o Swing e o JPA ainda não existia.
Aí acabamos fazendo nosso próprio framework de persistência. :cry:

Por usarmos Swing também não temos o problema que o pcalcado citou.

Desculpe minha ignorância, mas poderia me dizer quais os problemas que o Hibernate apresenta, quando usado com Swing?
É que estou trabalhando em um projeto, Java desktop com Swing, que está usando o Hibernate e queria saber o que pode acontecer mais pra frente.

Obrigado pela ajuda…

Então como vc fazia quando precisava referenciar um determinado registro no banco???
quando por exemplo em um sistema web vc fazia uma consulta que exibia diversos registros com a opção de alterar neste caso quando o usuario quiser alterar um registro este registro tera que ser mapeado com um identificador para que seja mandado para o servidor este identificador e com este identificador ele poder acessar e alterar um registro do bd… como fazer isto de uma maneira simples de modo que nao seja o id?

Como eu falei, no meu caso, não temos um sistema web. E, como eu falei, isso seria num “sistema ideal”. E geralmente coisas ideis são difíceis de se colocar em prática.

Mas isso também não significa que vc tenha que gerar o ID no braço. Essa tarefa pode ser delegada para as camadas inferiores. Esse id seria um getter que ninguém precisaria se preocupar com o valor, e seria usado tão somente para contornar essa limitação da arquitetura web.

As camadas inferiores podem fazer isso automaticamente, e vc não teria construtores com IDs explícitos.

Agora, isso é uma deficiência na forma como fazemos web hoje.

E que fique claro: eu não disse que o identificador não existe. Ele continua existindo. O BD precisa dele. Ele só não é publico, e fica gerenciado por classes inferiores.

[quote=ViniGodoy]Como eu falei, no meu caso, não temos um sistema web. E, como eu falei, isso seria num “sistema ideal”. E geralmente coisas ideis são difíceis de se colocar em prática.

Mas isso também não significa que vc tenha que gerar o ID no braço. Essa tarefa pode ser delegada para as camadas inferiores. Esse id seria um getter que ninguém precisaria se preocupar com o valor, e seria usado tão somente para contornar essa limitação da arquitetura web.

As camadas inferiores podem fazer isso automaticamente, e vc não teria construtores com IDs explícitos.

Agora, isso é uma deficiência na forma como fazemos web hoje.

E que fique claro: eu não disse que o identificador não existe. Ele continua existindo. O BD precisa dele. Ele só não é publico, e fica gerenciado por classes inferiores.[/quote]

Temos uma empresa séria! rs.
Mas legal isso.

Só uma coisa: como a camada inferior achar o id? Pelo equals/hashCode? Digo, uma hora a camada de cima vai passar o objeto pra ela, e como ela sabe localizá-lo no BD?

Como eu falei, o ID existe. Mas ele não é público. A classe de negócio, quando requisita serviços para camada de serviços, sabe o seu ID.

Quem não sabe é o usuário da classe de negócio.