Estou um pouco em desacordo com um desenvolvedor mais experiente sobre esse assunto e me perguntando o que os outros pensam sobre isso; nosso ambiente é Java, EJB 3, serviços etc.
O código que escrevi chama um serviço para obter e criar coisas. O problema que encontrei foi que recebi exceções de ponteiro nulo que não faziam sentido. Por exemplo, quando solicito ao serviço para criar um objeto, recebo nulo de volta; quando tento procurar um objeto com um ID válido conhecido, recebo nulo de volta. Passei algum tempo tentando descobrir o que havia de errado no meu código; como sou menos experiente, geralmente assumo que fiz algo errado, mas o motivo dos retornos nulos era a segurança. Se o principal de usuário que usa meu serviço não tiver as permissões corretas para o serviço de destino, ele simplesmente retornará nulo. A maioria dos outros serviços aqui também não está muito bem documentada, portanto, aparentemente, isso é apenas algo que você precisa saber.
Isso é um pouco confuso, pois um desenvolvedor escreve um código que interage com o serviço. Faria muito mais sentido para mim se o serviço apresentasse uma exceção que me dissesse que o usuário não tinha as permissões adequadas para carregar ou criar essa coisa; Eu saberia imediatamente por que meu serviço não estava funcionando conforme o esperado.
O desenvolvedor mais experiente que criou o serviço argumentou que solicitar os dados não é uma condição de erro e que exceções devem ser lançadas apenas em uma condição de erro, não quando o usuário não tiver acesso aos dados. Esses dados são frequentemente pesquisados em uma GUI e, para aqueles usuários sem as permissões corretas, essas coisas simplesmente "não existem". Então, resumindo: perguntar não é errado, portanto não há exceção. Os métodos Get retornam nulos porque para esses usuários essas coisas "não existem". Os métodos Create retornam nulo quando o usuário não tem permissão para criar essa coisa.
Isso é normal e / ou boa prática? Eu prefiro usar exceções porque acho muito mais fácil saber o que está acontecendo. Por isso, preferiria, por exemplo, também lançar uma NotFoundException se você solicitasse um objeto com um ID inválido, em vez de retornar nulo.
fonte
Respostas:
Pedir uma coisa pode não ser um erro, mas não ter permissões para algo que você pediu é certamente algum tipo de erro. As exceções são uma maneira alternativa de relatar condições excepcionais, a serem usadas em vez de valores de retorno especiais (como
null
, como você escreveu, não ajuda em nada, se houver> 1 razões possíveis para que as coisas dêem errado (mesmo que exista) exatamente 1 motivo possível agora, pode haver 2 motivos possíveis na próxima versão; portanto, usarnull
como valor de retorno uma indicação de falha seria um problema). Se o serviço não relatar de forma alguma por que não fará o que você pediu, é definitivamente um design ruim.A utilização de um valor de retorno especial (por exemplo, números inteiros negativos são úteis para funções que normalmente retornam um número inteiro não negativo), uma exceção, um manipulador de erros global ou criador de logs etc., é um detalhe de implementação no final. A escolha depende do idioma, da situação, das convenções e também é uma questão de gosto. O ponto principal é que deve haver alguma maneira direta de descobrir por que algo não funciona. Caso contrário, sua única opção é vasculhar opções diferentes e descobrir o que se correlaciona com o comportamento da caixa preta, e isso é perda de tempo.
String.substring()
lança umIndexOutOfBoundsException
se o índice estiver fora dos limites. Não consigo pensar em nenhuma vantagem em retornarnull
, embora - filosoficamente - alguém possa argumentar que aString
não contém nada fora de seus limites, entãonull
seria um valor de retorno lógico na época. Ser lógico-filosófico e ser prático são obviamente dois animais diferentes.fonte
substring
retornar uma referência nula. IMHO, deve haver duas funções separadas - uma das quais promete retornar o número solicitado de caracteres ou lançar uma exceção, e uma das quais retorna o máximo possível. Cada método seria substancialmente superior ao outro em alguns contextos.Tudo se resume ao que é o contrato. Se o seu contrato diz que você pode solicitar algo que não existe, ele deve dizer o que acontece (objeto nulo ou nulo).
Por outro lado, se o seu contrato diz que você deve chamar um método diferente primeiro (
DoesSomethingExist()
) e depois chamar oGet
método, então o contrato pode dizer que você só pode obter as coisas que existem e lançar uma exceção se não o fizerem. A mensagem de exceção pode dizer algo como "Certifique-se de ligarDoesSomethingExist()
primeiro", que é uma mensagem de erro útil.fonte
findAllThings
método, eu diria que é apropriado retornar uma lista ou um subconjunto vazio se houver algumas ou todas as coisas que você não tem permissão para ver. Da mesma forma, em um blog, posso listar apenas as postagens para edição pertencentes ao usuário atual. Mas se esse usuário, em seguida, tentou ajustar o url e editar um post diferente ...Não existe uma resposta única para a pergunta. A utilização de exceções ou o retorno nulo depende da situação.
Em vez de olhar isso puramente do ponto de vista dogmático, observe a interface como uma interface de usuário . As interfaces do usuário devem ser utilizáveis . Portanto, independentemente de suas próprias opiniões sobre a maneira "certa" de fazer algo, escolha o método que é mais utilizável da perspectiva de alguém que usa sua interface.
Se o chamador precisar saber por que um objeto não está sendo retornado, uma exceção é apropriada. Se, no entanto, o conceito geral for "se você não tem permissão, ela não existe", o valor nulo é aceitável.
Especificamente no seu caso, eu diria que os nulos são perfeitamente aceitáveis para procurar um item se o chamador for primeiro solicitado a fazer login ou conectar-se ao servidor. É quando você é informado de que tem ou não permissão. Depois de passar pelo portão, é razoável que, ao procurar algo que você não tem permissão para ver (ou mesmo saiba que existe), você deve obter um nulo.
Se, por outro lado, você não tiver uma etapa inicial de conexão ou login, uma exceção fará sentido. Se o chamador sabe que um item existe e não o recupera, a API não está sendo útil para retornar apenas um nulo.
Para criar um item, no entanto, é uma história diferente. Presumivelmente, pode haver várias razões para isso falhar - sem permissões, parâmetros incorretos, servidor sem memória, etc. Se o desenvolvedor receber um nulo para todas essas condições, ele não terá como determinar um curso de ação adequado. .
Portanto, para responder à pergunta, pergunte-se qual é a solução mais utilizável do ponto de vista de alguém que usa o serviço. Pode ser que o modo como você o esteja usando seja atípico e, no caso mais comum, um nulo seja a resposta certa.
Portanto, não entre em uma guerra religiosa por causa disso, decida o que é certo para esse problema em particular.
fonte
Eu definitivamente acho que é um design ruim . Ponteiro nulo não é uma resposta válida para mim e pode ser complicado de gerenciar.
Se o usuário tentar conectar um serviço sem a credencial adequada, devo responder com uma resposta clara e concisa. A resposta pode ser uma exceção ou um objeto especial, mas não nulo.
Você deve deixar a resposta nula quando o link de rede estiver quebrado ou outro mau funcionamento crítico inesperado.
Além disso, o tempo que você gasta para entender por que você obteve um nulo é um argumento forte. Qualquer parte do código deve ser fácil de entender e usar. Ter um valor nulo não é o caso.
fonte
Tendo em mente um bom design de software, pense na vida do seu projeto.
Ao retornar
null
, como já foi dito, você não fornece nenhuma informação ao cliente. Veja o que aconteceu com você, a princípio você não percebeu onde estava o problema. Além disso, se nenhuma documentação for fornecida, isso é uma bagunça.Ao lançar uma exceção, você pode dizer o que deu errado. Você pode até personalizar o texto exibido para ser mais específico, se desejar.
Por outro lado, ao retornar,
null
você faz o cliente investigar o que está acontecendo.Além disso, você percebeu que havia um problema porque havia outro lugar a
NullPointerException
. Agora imagine que você não armazena o retorno dessa função ... Você será forçado a cercar cada chamada dessa função com umif else
bloco ...Do meu ponto de vista, retornar
null
é uma prática ruim.fonte
Do meu ponto de vista, isso não faz sentido.
A consulta de dados sem permissão deve resultar em uma exceção, porque é um resultado inesperado - sem resultado - sem acesso adequado.
Analogia : o código de resposta para um
GET
sem autorização não está200 ok
sem dados, na verdade é401 Unauthorized
.fonte
Retornar nulo não é bom. Isso não diz nada. Para dar o seu exemplo, se um aplicativo está tentando procurar algo e a resposta é nula para os dois problemas de segurança e se o item não existe, como você sabe a diferença entre os dois?
Uma resposta significativa pode permitir que o aplicativo faça escolhas lógicas sobre o que fazer em seguida ou como resolver problemas.
fonte
Se a causa raiz for um usuário não autenticado, prefiro uma resposta HTTP 401 rígida, talvez com um redirecionamento para uma página de mensagem bonita (e uma notificação para alguém que se importa). As causas relacionadas à autorização são mais caso a caso; existem argumentos para retornar erros HTTP (403, por exemplo) e argumentos para retornar códigos / mensagens especiais bem formados na resposta do serviço.
Exceções devem ser usadas apenas em circunstâncias excepcionais e significam que algo deu errado. Eu discordo que eles devem estar sobrecarregados para significar "não permitido". (O mesmo vale para o valor de retorno nulo: discordo que ele deva ser usado para significar "não permitido".)
fonte
Para fazer o papel de advogado do diabo, tentarei tomar o lado de retornar nulo.
Na minha opinião, há apenas uma situação em que esse tipo de resposta é quase aceitável e é, como neste caso, quando a segurança está envolvida.
É muito fácil divulgar acidentalmente detalhes do seu sistema que pessoas não autorizadas não devem conhecer. Isso deve ser evitado.
Pegue, por exemplo, um verificador de nome de usuário e senha. Retornar um erro "Nome de usuário não encontrado" e um erro "Senha incorreta" como códigos de erro separados obviamente abriria você para sérios problemas de segurança, já que alguém poderia primeiro procurar um nome de usuário válido e depois procurar uma senha. Retornar um "nome de usuário / senha inválido" genérico seria uma opção melhor.
Assim, nesse caso em particular, eu diria que está quase certo retornar,
null
mas concordo que seria muito desagradável trabalhar com isso.fonte
null
é exatamente a resposta menos útil. Quase qualquer outra coisa poderia ser usada para descobrir algo sobre o sistema. A razão pela qual a OP reclamou foi porque onull
retorno não apenas explicou nada, mas também foi inútil. Esse é o objetivo deliberado ... não dizer absolutamente nada e ser inútil. Missão cumprida em minha opinião.Eu acho que o retorno nulo é hostil, quando o cliente invoca esse método e retorna nulo, o cliente não sabe o que aconteceu e por que retornou nulo. Portanto, devemos executar a execução, o que faz sentido e fornecer uma documentação para descrever essa execução.
fonte