Alternativas para return null

Quando um método por exemplo buscaUsuarioPor(id) não encontra um usuario com aquele id o que deveriamos retornar?
No caso de coleções de objetos o Collections.emptyList() é sempre minha primeira opção, mas no caso de objetos unicos sempre fico na dúvida. Acho estranho retornar null, li alguns artigos onde falavam para retornar objetos vazios ou instancias que herdam de Usuario por exemplo onde verificariamos que aquela é uma instancia de um Usuario invalido… Mas nesse ultimo caso talvez seja apenas a troca de uma consulta == null por instanceOf…

Gostaria de conhecer a opnião de vocês nesse assunto, conhecer novas idéias para resolver esse problema, e encontrar uma forma mais elegante de tratar esses casos.

Uma consulta que retornaria uma lista, retorna uma lista vazia. Uma consulta de resultado único, retorna null.

Talvez uma boa alternativa seja o Null Object pattern.

Tem um exemplo legal aqui

Um referencia apontando para null quer dizer que não existe objeto para ser manipulado. Ou seja, não tem nada haver com elegância ou não. É uma questão de semântica. Como vc acha q deveria se apontar um objeto que não existe? kkkk

  • Ou retorna nullo, em caso da consulta poder não encontrar o registro
  • ou lança uma exception de aplicação caso ser obrigatória a existência do objeto dentro do contexto da solução.

[quote=FernandoFranzini]Um referencia apontando para null quer dizer que não existe objeto para ser manipulado. Ou seja, não tem nada haver com elegância ou não. É uma questão de semântica. Como vc acha q deveria se apontar um objeto que não existe? kkkk

  • Ou retorna nullo, em caso da consulta poder não encontrar o registro
  • ou lança uma exception de aplicação caso ser obrigatória a existência do objeto dentro do contexto da solução.
    [/quote]

Talvez

  • Ou trazer um objeto “vazio”

Gostei da abordagem do Null Object pattern citado pelo allandequeiroz.
Acho que é uma boa alternativa. Como é uma boa prática retornar uma lista vazia ao invés de null em um método, tb acho válido retornar um usuário “vazio” ao invés de null.

[quote=FernandoFranzini]Um referencia apontando para null quer dizer que não existe objeto para ser manipulado. Ou seja, não tem nada haver com elegância ou não. É uma questão de semântica. Como vc acha q deveria se apontar um objeto que não existe? kkkk

  • Ou retorna nullo, em caso da consulta poder não encontrar o registro
  • ou lança uma exception de aplicação caso ser obrigatória a existência do objeto dentro do contexto da solução.
    [/quote]

Pelo contrário, o null é totalmente fora da semântica. Por exemplo, eu tenho um método que retorna o usuário autenticado ou ele traz o usuário correto ou um usuário vazio. Null é um conceito de programação, fora do domínio. Até porque null em java não é objeto…ele pode ser qualquer coisa. Ao contrário do NullUser que falaram que é um usuário vazio, é muito mais semântico e na hora de verificar é muito mais fácil ler e não dar NPE (NullPointerException)

Também acho que exceção é usado apenas para…exceções :smiley:

O usuário não conseguir se autenticar não é exceção é algo que pode ocorrer…usar exceção para fazer uma comunicação ao usuário não é o caminho eu acho…

é claro que não é mesmo…como seria um objeto nullo? kkkkkk
Nullo é ausência de objeto, que tb deve ser tratado corretamente dentro na logica do programa…como seria nunca ter um ponteiro nulo dentro do seu programa?
Eu discordo completamente…inclusive na minha prova de SCJD usei intensivamente essa abordagem e não perdi nota.
Eu acho que usar o patter null é legal sim, super elegante…mas tratar null da forma simples e básica que ele é tb é um boa pratica sim.
Fica a criterio de cada um usar o mais coerente para seu projeto…
T+

é claro que não é mesmo…como seria um objeto nullo? kkkkkk
[/quote]

Só um adendo, em Ruby nil (que é o null) é um objeto. (Sim, você pode fazer acessar métodos dele) :smiley:

E sim é possível minimizar bastante os null do seu projeto e fica bom viu? Você deveria tentar

As certificações nem sempre dizem o correto na hora de programar, até porque o Joshua Bloch no seu livro “Effective Java” fala sobre isso de evitar de usar null, principalmente em coleções.

Mas cada um, cada um né?

Não acho não…se fosse assim que valor teria não é mesmo? So para te esclarecer, na prova SCJD não existe correto ou errado…vc precisa defender sua decisão coerentemente, com justificativas arquiteturais.

Acredito que se a abordagem garantir nos caso a robustez ok. Não existe opção melhor…e sim trabalhar com elas, seus pros e contras.
A decisão fica aberta para cada um…

No livro Clean Code, Uncle Bob colocou dois tópicos para falar sobre isso: Don’t Return Null e Don’t Pass Null. Em resumo, se você usar null, muito provavelmente você precisa verificar se um objeto retornado é nulo, ou pegar uma possível NullPointerException (às vezes, tem de fazer os dois). É trabalho desnecessário e nada mais, não é uma boa prática.

Creio que uma prova disso são as formas propostas para evitar seu uso, como o NullObject já sugerido, ou o uso de ferramentas como Objects.firstNonNull do guava.

Não acho não…se fosse assim que valor teria não é mesmo? So para te esclarecer, na prova SCJD não existe correto ou errado…vc precisa defender sua decisão coerentemente, com justificativas arquiteturais.[/quote]

É por isso que tem gente que defende que certificação não quer dizer muita coisa…mas vamos voltar ao tópico certo? O importante da discussão é ter os dois lados mostrando os seus argumentos.

Vamos esperar para ver quem mais se habilitar a discutir com a gente. :smiley:

Ah e só mais uma coisa, robustez é importante, mas um bom design de classes, código limpo e de fácil manutenção são tão importantes quanto. (Por isso que tento minimizar os nulls, eles poluem o código, deixa mais difícil de ler e obrigam a fazer mais ifs)

Agora sim temos uma boa justificativa arquitetural… parabéns!!! era isso que eu esperava de vc…Veja que eu não estava defendendo a certificação…na verdade a sua justificativa foi invalidar a credencialidade da certificação que no caso não tem nada relacionado com o assunto.
Vale lembrar que tem os contras tb…mesmo retornando o objetoNull polimórfico a aplicação ainda sim pode ter comportamentos não adequados, uma vez q esse objeto NULL não pode se comportar como tal durante a execução do programa.

Fernando, em momento nenhum quis descredenciar a certificação, só acho ruim o argumento de programo assim porque eu fiz na certificação e eles aceitaram.

Certificação prova muitas coisas, mas não se você sabe programar, e quando falei que tem pessoas (e empresas) que não ligam pra certificação é uma realidade de mercado, existem empresas que preferem ver o seu código do que monte de papel. Assim como existem empresas, que procuram profissionais certificados. Enfim, mas não é essa a questão do tópico.

Sei que a abordagem que comentei tem suas falhas, mas ainda acho melhor do que usar o puro e simplesmente null, porque acho que tem mais pontos contras do que positivos.

Por isso, estou acompanhando esse tópico…quero ver quais outras abordagens existem.

Então javablue a questão é que na SCJD é uma certificação diferenciada, uma vez que nela vc é obrigado a escrever um solução parcial e seu código (clareza, flexibilidade, OOP, bla, bla, bla etc) é avaliado sim. Procure mais informações (http://fernandofranzini.wordpress.com/2010/12/07/dicas-para-oracle-certified-master-java-developer/). Mas voltando ao assunto, existem 3 opções até aqui:

  1. Usar null
  2. Usar null patter
  3. Não usar null lançando exceptions.
    Alguem ve outras?

[quote=FernandoFranzini]Mas voltando ao assunto, existem 3 opções até aqui:

  1. Usar null
  2. Usar null patter
  3. Não usar null lançando exceptions.
    Alguem ve outras?[/quote]

Particulamente, gosto da idéia do NullPattern (principalmente em Java).

Mas você pode também retornar Talvez.

Discusões assim duram vidas inteiras…

MINHA OPINIÂO

se o retorno for uma lista creio q o ideial é retornar um List instanciado porem vazio (isEmpty() == true)
no caso de um unico registro creio que se deva retornar nulo.

Penso assim pelo fluxo simples da logica, busquei um registro, ele não existe então é nulo e não um registro q existe porem é vazio.

So para constar, o Hibernate possui dois metodos para carregar objetos pela pk. o metodo get (acessado pelo objeto da session) e o metodo load (tambem acessado pelo objeto session). O get qnd não encontra nenhum registro baseado na pk passada ele retorna nulo. Já o load lança uma Exceção.

[quote]Penso assim pelo fluxo simples da logica, busquei um registro, ele não existe então é nulo e não um registro q existe porem é vazio.
So para constar, o Hibernate possui dois metodos para carregar objetos pela pk. o metodo get (acessado pelo objeto da session) e o metodo load (tambem acessado pelo objeto session). O get qnd não encontra nenhum registro baseado na pk passada ele retorna nulo. Já o load lança uma Exceção. [/quote]
Tb tenho a mesma opinião… :smiley:

Pedes para alguém ir buscar uma cerveja ao frigorífico.

Opções possíveis

  • Não trazer nenhuma cerveja porque não há.
  • Trazer uma garrafa vazia ou um desenho de uma garrafa ou qualquer coisa que seja só porque não há nenhuma cerveja.

Qual vos parece melhor e mais acertada?

Para coleções acho que já é consenso que seja retornada uma instância vazia.

Agora para objetos individuais, minha opinião é que depende do contexto.
Sempre que fizer sentido para o domínio a existência de um NullObject, utilize (exemplo do SecurityManager no livro do Joshua Block).
Se a inexistência do objeto constitui uma situação excepcional / erro de negócio, lance exceção (por exemplo, um método de login que retorna o usuário após validação dos dados).
Caso contrário, simplesmente é uma procura que não achou resultado, retorne null.

Ah… acrescentando: Se em muitos momentos diferentes tiver que ser feito o famoso if obj != null , é mais um motivo para favorecer o uso de NullObject.

[quote=pmlm]Pedes para alguém ir buscar uma cerveja ao frigorífico.

Opções possíveis

  • Não trazer nenhuma cerveja porque não há.
  • Trazer uma garrafa vazia ou um desenho de uma garrafa ou qualquer coisa que seja só porque não há nenhuma cerveja.

Qual vos parece melhor e mais acertada?[/quote]

Não entendi sua analogia. Você está defendendo ou criticando o uso do null?

Traduzindo para o java, retornar null é diferente de avisar que não tem cerveja.
Quando seu método retorna null, não há indicação que não tinha cerveja, ele executou normalmente.

Você só descobriria que não é realmente cerveja ao tentar usar e algo de excepcional ocorresse (as NPE do java).

Da mesma forma, quando você pede uma cerveja ao garçom e ele te traz uma garrafa, não é necessário perguntar:

  • Isso aqui é uma cerveja?

Se ele te trouxe silenciosamente a garrafa, espera-se que seja cerveja.

Pela sua analogia, o mais correto seria lançar uma exceção Não Tem Mais Cerveja, que seria o garçom avisando que acabou.