É melhor retornar valores nulos ou vazios de funções / métodos em que o valor de retorno não está presente?

135

Estou procurando uma recomendação aqui. Estou lutando para saber se é melhor retornar um valor nulo ou vazio de um método quando o valor de retorno não está presente ou não pode ser determinado.

Tome os dois métodos a seguir como exemplo:

string ReverseString(string stringToReverse) // takes a string and reverses it.
Person FindPerson(int personID)    // finds a Person with a matching personID.

Em ReverseString(), eu diria retornar uma string vazia porque o tipo de retorno é string, então o chamador está esperando isso. Além disso, dessa maneira, o chamador não precisaria verificar se um NULL foi retornado.

Em FindPerson(), retornar NULL parece um ajuste melhor. Independentemente de new Person()ser retornado NULL ou não um Objeto Pessoa ( ) vazio, o chamador terá que verificar se o Objeto Pessoa está NULL ou vazio antes de fazer alguma coisa (como chamar UpdateName()). Então, por que não apenas retornar NULL aqui e, em seguida, o chamador precisa apenas verificar NULL.

Alguém mais luta com isso? Qualquer ajuda ou insight é apreciada.

PB
fonte
2
Isso varia. Você também pode argumentar que o método deve interromper valores incorretos antecipadamente, por exemplo, se seu parâmetro stringToReverse é passado como vazio ou nulo. Se você executou essa verificação (retornou uma exceção), ela sempre retornará algo diferente de nulo.
Aaron McIver
Fowler POEAA - pág. 496 Padrões base - caso especial (objeto nulo) Java efetivo de Bloch, 2ª edição Item 43: Retornar matrizes ou coleções vazias, e não
nulas
1
@ Boris Não vi seu comentário. Na verdade, acabei de postar o Caso Especial como resposta.
Thomas Owens
@ Thomas Eu não vejo nenhum problema nele :). Quanto à questão, é uma questão de bom senso de qualquer maneira.
Boris Treukhov 17/11
Um comentário interessante é que em bancos de dados Oracle NULL e uma string vazia são os mesmos
WuHoUnited

Respostas:

77

O StackOverflow tem uma boa discussão sobre esse tópico exato nas perguntas e respostas . Na pergunta mais votada, a kronoz observa:

Retornar nulo geralmente é a melhor ideia se você pretende indicar que nenhum dado está disponível.

Um objeto vazio indica que os dados foram retornados, enquanto o retorno nulo indica claramente que nada foi retornado.

Além disso, retornar um nulo resultará em uma exceção nula se você tentar acessar membros no objeto, o que pode ser útil para destacar o código de buggy - tentar acessar um membro do nada não faz sentido. O acesso a membros de um objeto vazio não falhará, o que significa que os erros podem não ser descobertos.

Pessoalmente, gosto de retornar cadeias vazias para funções que retornam cadeias para minimizar a quantidade de manipulação de erros que precisa ser implementada. No entanto, você precisará garantir que o grupo com o qual você trabalha siga a mesma convenção - caso contrário, os benefícios desta decisão não serão alcançados.

No entanto, como observou o pôster na resposta do SO, os nulos provavelmente devem ser retornados se um objeto for esperado, para que não haja dúvida sobre se os dados estão sendo retornados.

No final, não existe a melhor maneira de fazer as coisas. Construir um consenso de equipe acabará por impulsionar as melhores práticas de sua equipe.

JW8
fonte
8
Pessoalmente, gosto de retornar cadeias vazias para funções que retornam cadeias para minimizar a quantidade de manipulação de erros que precisa ser implementada. Nunca entendi esse argumento. A verificação nula é o que, no máximo <10 caracteres? Por que agimos como se este fosse um trabalho dobrado?
Aaron McIver
19
Ninguém disse que estava dobrando o trabalho. Mas é trabalho. Ele adiciona um caso especial ao código, o que significa mais uma ramificação para testar. Além disso, interrompe o fluxo do código. for x in list_of_things() {...}é sem dúvida mais rápido para Grokar entãol = list_of_things(); if l != null {...}
Bryan Oakley
5
@ Bryan: há uma grande diferença entre uma lista vazia de valores e uma string vazia. Uma string raramente representa uma lista de caracteres.
kevin Cline
3
@ Kevin Cline: é claro. Mas no caso de uma string, você pode querer que ela apareça em um log, seja nulo ou não. Ter que verificar se é nulo para que você possa imprimir uma sequência vazia ofusca a intenção real. Ou talvez seja algo como um campo de banco de dados que contém conteúdo contribuído pelo usuário que você deseja adicionar a uma página da web. É mais fácil de fazer emit(user.hometown)do queif user.hometown == null { emit("") else {emit(user.hometown)}
Bryan Oakley
1
Não é apenas uma digitação extra (não é grande coisa), mas afeta a legibilidade. Eu pessoalmente acho o código com um monte de cheques nulos que distraem.
ToddR
82

Em todo o código que escrevo, evito retornar nullde uma função. Eu li isso em Clean Code .

O problema com o uso nullé que a pessoa que usa a interface não sabe se nullé um resultado possível e se precisa verificar se há um not nulltipo de referência.

No F #, você pode retornar um optiontipo, que pode ser some(Person)ou none, portanto, é óbvio para o chamador que ele deve verificar.

O padrão C # (anti-) análogo é o Try...método:

public bool TryFindPerson(int personId, out Person result);

Agora eu sei que as pessoas disseram que odeiam o Try...padrão porque ter um parâmetro de saída interrompe as idéias de uma função pura, mas na verdade não é diferente de:

class FindResult<T>
{
   public FindResult(bool found, T result)
   {
       this.Found = found;
       this.Result = result;
   }

   public bool Found { get; private set; }
   // Only valid if Found is true
   public T Result { get; private set;
}

public FindResult<Person> FindPerson(int personId);

... e para ser sincero, você pode assumir que todo programador .NET conhece o Try...padrão porque é usado internamente pela estrutura .NET. Isso significa que eles não precisam ler a documentação para entender o que fazem, o que é mais importante para mim do que seguir a visão de funções de alguns puristas (entender que isso resulté um outparâmetro, não um refparâmetro).

Então, eu continuaria TryFindPersonporque você parece indicar que é perfeitamente normal não conseguir encontrá-lo.

Se, por outro lado, não houver motivo lógico para o chamador fornecer um personIdque não existe, eu provavelmente faria o seguinte:

public Person GetPerson(int personId);

... e depois lançaria uma exceção se fosse inválida. O Get...prefixo implica que o chamador sabe que deve ter sucesso.

Scott Whitlock
fonte
28
+1, eu responderia a essa pergunta com uma referência ao código limpo, se você ainda não o fez. Gosto do mantra: "Se a sua função não pode fazer o que diz, então lança uma exceção". Muuuch melhor do que verificar se há nulos a cada dúzia de linhas ...
Graham
13
Eu desisti de assumir qualquer coisa sobre o conhecimento das pessoas.
CaffGeek
5
"O problema com o uso de nulo é que a pessoa que usa a interface não sabe se nulo é um resultado possível e se deve procurar por isso, porque não há um tipo de referência que não seja nulo". Como os tipos de referência podem ser nulos, você não pode sempre assumir que nulo é um resultado possível?
Tommy Carlier
4
Se uma função retornar um ponteiro (C / C ++) ou uma referência a um objeto (Java), sempre presumo que ela possa retornar nulo.
Giorgio
7
"O problema com o uso de nulo é que a pessoa que usa a interface não sabe se nulo é um resultado possível e se deve procurar por isso, [...]" "Se um método pode retornar nulo, deve ser explicitamente mencionado como parte do contrato da API.
Zsolt Török
28

Você pode experimentar o padrão de Caso Especial de Martin Fowler , de Paterns of Enterprise Application Architecture :

Nulos são coisas estranhas em programas orientados a objetos, porque eles derrotam o polimorfismo. Geralmente, você pode chamar foo livremente em uma referência variável de um determinado tipo sem se preocupar se o item é do tipo exato ou de uma subclasse. Com uma linguagem fortemente tipada, você pode até solicitar que o compilador verifique se a chamada está correta. No entanto, como uma variável pode conter nulo, você pode encontrar um erro de tempo de execução invocando uma mensagem em nulo, o que fornecerá um rastreamento de pilha agradável e amigável.

Se for possível que uma variável seja nula, lembre-se de cercá-la com código de teste nulo para fazer a coisa certa se houver um nulo. Muitas vezes, a coisa certa é a mesma em muitos contextos, então você acaba escrevendo código semelhante em muitos lugares - cometendo o pecado da duplicação de código.

Os nulos são um exemplo comum de tais problemas e outros surgem regularmente. Nos sistemas numéricos, você precisa lidar com o infinito, que possui regras especiais para coisas como adição que quebram os invariantes usuais de números reais. Uma das minhas primeiras experiências em software comercial foi com um cliente de serviços públicos que não era totalmente conhecido, conhecido como "ocupante". Tudo isso implica alterar o comportamento usual do tipo.

Em vez de retornar nulo ou algum valor ímpar, retorne um Caso Especial que tenha a mesma interface que o chamador espera.

Thomas Owens
fonte
Eu me deparei com esse cenário, mas somente após o lançamento do software. Meus dados de teste nunca os acionaram, por isso foi um pouco inesperado e muito difícil de depurar. Embora eu não tenha resolvido isso com o padrão de Caso Especial, é bom estar ciente disso.
samis 6/03/2017
14

Eu acho ReverseString()que retornaria a string invertida e lançaria um IllegalArgumentExceptionse passado em a Null.

Eu acho que FindPerson()deveria seguir o padrão NullObject ou criar uma exceção desmarcada sobre não encontrar algo, se você sempre conseguir encontrar algo.

Ter que lidar com isso Nullé algo que deve ser evitado. Tendo Nullem idiomas foi chamado de erro de bilhões de dólares por seu inventor!

Eu chamo de erro do meu bilhão de dólares. Foi a invenção da referência nula em 1965. Naquela época, eu estava projetando o primeiro sistema abrangente de tipos para referências em uma linguagem orientada a objetos (ALGOL W).

Meu objetivo era garantir que todo o uso de referências fosse absolutamente seguro, com a verificação realizada automaticamente pelo compilador. Mas não pude resistir à tentação de colocar uma referência nula, simplesmente porque era muito fácil de implementar.

Isso levou a inúmeros erros, vulnerabilidades e falhas no sistema, que provavelmente causaram um bilhão de dólares de dor e danos nos últimos quarenta anos.

Nos últimos anos, vários analisadores de programas como o PREfix e o PREfast na Microsoft foram usados ​​para verificar as referências e dar avisos se houver um risco de não serem nulos. Linguagens de programação mais recentes, como Spec #, introduziram declarações para referências não nulas. Esta é a solução, que rejeitei em 1965.

Tony Hoare


fonte
11

Retornar uma opção . Todos os benefícios de retornar um valor inválido diferente (como poder ter valores vazios em suas coleções) sem nenhum risco de NullPointerException.

hugomg
fonte
1
Interessante. Como implementar uma opção em Java? E em C ++?
Giorgio
1
@Giorgio, para Java, as bibliotecas Guava, do Google, têm uma classe chamada Opcional .
Otávio Macedo
1
Para C ++, háboost::optional<T>
MSalters
8

Eu vejo os dois lados desse argumento e percebo que algumas vozes bastante influentes (por exemplo, Fowler) advogam não retornar nulos para manter o código limpo, evitar blocos extras de tratamento de erros etc.

No entanto, tenho a tendência de apoiar os proponentes de retornar nulo. Acho que há uma distinção importante em invocar um método e ele responder com eu não tenho nenhum dado e responder com eu tenho essa String vazia .

Desde que eu vi algumas das discussões referenciando uma classe Person, considere o cenário em que você tenta procurar uma instância da classe. Se você passar algum atributo do localizador (por exemplo, um ID), um cliente poderá verificar imediatamente se há nulo para ver se nenhum valor foi encontrado. Isso não é necessariamente excepcional (portanto, não precisa de exceções), mas também deve ser documentado claramente. Sim, isso requer um certo rigor por parte do cliente, e não, não acho que isso seja algo ruim.

Agora considere a alternativa em que você retorna um objeto Person válido ... que não contém nada. Você coloca nulos em todos os seus valores (nome, endereço, favoriteDrink) ou agora preenche aqueles com objetos válidos, mas vazios? Como seu cliente agora determina que nenhuma Pessoa real foi encontrada? Eles precisam verificar se o nome é uma String vazia em vez de nula? Esse tipo de coisa não vai realmente levar a muito ou mais desordem de código e instruções condicionais do que se tivéssemos acabado de procurar por nulo e seguimos em frente?

Novamente, há pontos em ambos os lados desse argumento com os quais eu poderia concordar, mas acho que isso faz mais sentido para a maioria das pessoas (tornando o código mais sustentável).

RonU
fonte
A diferença é: " retorna FindPersonou GetPersonnula ou lança uma exceção se a chave não existir?" Como usuário da API, simplesmente não sei e tenho que verificar a documentação. Por outro lado, bool TryGetPerson(Guid key, out Person person)não exige que eu verifique a documentação e sei que uma exceção não é lançada, o que equivale a uma circunstância não excepcional. Esse é o ponto que estou tentando expressar na minha resposta.
Scott Whitlock
4
Eu acho que as pessoas se apegaram demais a exceções. As exceções são ruins e consomem recursos. Sem mencionar que as pessoas tentam pegar declarações sem resolver nada. Exceções são sinais claros de que algo deu errado. Por exemplo, referências nulas lança uma exceção, porque é claramente errado fazer referência a objetos nulos. É errado usá-lo para verificar se a pessoa foi encontrada ou não.
Vladimir Kocjancic
1
@ VladimirKocjancic: Eu concordo totalmente: exceções devem ser usadas para situações excepcionais, como bugs de software, falhas de hardware, configuração incorreta do sistema. Se você estiver computando uma função parcial (como findPerson), é absolutamente normal não obter nenhum resultado. Isso não deve levar a uma exceção.
Giorgio
6

Retorne nulo se precisar saber se o item existe ou não. Caso contrário, retorne o tipo de dados esperado. Isto é especialmente verdade se você estiver retornando uma lista de itens. Geralmente, é seguro supor que, se o chamador estiver querendo uma lista, ele desejará repetir a lista. Muitos idiomas (a maioria? Todos?) Falham se você tentar iterar por nulo, mas não quando você iterar por uma lista que está vazia.

Acho frustrante tentar usar código como este, apenas para que ele falhe:

for thing in get_list_of_things() {
    do_something_clever(thing)
}

Eu não deveria ter que adicionar um caso especial para o caso quando não há coisas .

Bryan Oakley
fonte
7
Nos casos em que uma lista ou outro grupo de valores é esperado, sempre escolho retornar uma lista vazia, exatamente por esse motivo. A ação padrão (repetindo uma lista vazia) quase sempre está correta e, se não estiver, o chamador pode verificar explicitamente se a lista está vazia.
TMN
5

Depende da semântica do método. Você pode especificar, seu método aceita apenas "Não nulo". Em Java, você pode declarar isso usando algumas anotações de metadados:

string ReverseString(@NotNull String stringToReverse)

De alguma forma, você deve especificar o valor de retorno. Se você declarar, aceita apenas valores NotNull, é obrigado a retornar uma sequência vazia (se a entrada também for uma sequência vazia).

O segundo caso é um pouco complicado em sua semântica. Se esse método é retornar uma pessoa por sua chave primária (e é esperado que a pessoa exista), a melhor maneira é lançar uma exceção.

Person FindPerson(int personID)

Se você procurar uma pessoa por algum ID adivinhado (o que me parece estranho), é melhor declarar esse método como @Nullable.

Martin Vejmelka
fonte
3

Eu recomendaria usar o padrão Null Object sempre que possível. Ele simplifica o código ao chamar seus métodos, e você não consegue ler códigos feios como

if (someObject != null && someObject.someMethod () != whateverValue)

Por exemplo, se um método retorna uma coleção de objetos que se encaixam em algum padrão, retornar uma coleção vazia faz mais sentido do que retornar null, e a iteração sobre essa coleção vazia não terá praticamente nenhuma penalidade de desempenho. Outro caso seria um método que retorna a instância da classe usada para registrar dados, retornando um objeto Null em vez de nullpreferível na minha opinião, pois não força os usuários a sempre verificar se a referência retornada é null.

Nos casos em que retornar nullfaz sentido (chamando o findPerson ()método por exemplo), eu tentaria pelo menos fornecer um método que retorne se o objeto estiver presente ( personExists (int personId)por exemplo), outro exemplo seria o containsKey ()método Mapem Java. Isso torna o código dos chamadores mais limpo, pois você pode ver facilmente que existe a possibilidade de o objeto desejado não estar disponível (a pessoa não existe, a chave não está presente no mapa). Constantemente verificando se uma referência nullofusca o código na minha opinião.

Laf
fonte
3

null é a melhor coisa para retornar se e somente se as seguintes condições se aplicarem:

  • o resultado nulo é esperado em operação normal . Pode-se esperar que você não consiga encontrar uma pessoa em algumas circunstâncias razoáveis; portanto, findPerson () retornando null é bom. No entanto, se for uma falha genuinamente inesperada (por exemplo, em uma função chamada saveMyImportantData ()), você deverá lançar uma exceção. Há uma dica no nome - as exceções são para circunstâncias excepcionais!
  • null é usado para significar "não encontrado / sem valor" . Se você quer dizer outra coisa, retorne outra coisa! Bons exemplos seriam operações de ponto flutuante retornando Infinity ou NaN - esses são valores com significados específicos, portanto, seria muito confuso se você retornasse nulo aqui.
  • A função deve retornar um único valor , como findPerson (). Se ele foi projetado para retornar uma coleção, por exemplo, findAllOldPeople (), então é melhor uma coleção vazia. Um corolário disso é que uma função que retorna uma coleção nunca deve retornar nula .

Além disso, certifique-se de documentar o fato de que a função pode retornar nula.

Se você seguir essas regras, os nulos serão inofensivos. Observe que, se você esquecer de procurar nulo, normalmente receberá uma NullPointerException imediatamente depois, o que geralmente é um bug muito fácil de corrigir. Essa abordagem de falha rápida é muito melhor do que ter um valor de retorno falso (por exemplo, uma string vazia) que é propagada silenciosamente pelo sistema, possivelmente corrompendo dados, sem gerar uma exceção.

Por fim, se você aplicar essas regras às duas funções listadas na pergunta:

  • FindPerson - seria apropriado que essa função retorne nulo se a pessoa não foi encontrada
  • ReverseString - parece que nunca deixaria de encontrar um resultado se passasse uma string (já que todas as strings podem ser revertidas, incluindo a string vazia). Portanto, nunca deve retornar nulo. Se algo der errado (falta de memória?), Isso deve gerar uma exceção.
Mikera
fonte
1

Na minha opinião, há uma diferença entre retornar NULL, retornar algum resultado vazio (por exemplo, a string vazia ou uma lista vazia) e lançar uma exceção.

Eu normalmente tomo a seguinte abordagem. Considero uma função ou método chamada f (v1, ..., vn) como a aplicação de uma função

f : S x T1 x ... x Tn -> T

onde S é o "estado do mundo" T1, ..., Tn são os tipos de parâmetros de entrada e T é o tipo de retorno.

Primeiro tento definir esta função. Se a função for parcial (ou seja, existem alguns valores de entrada para os quais não está definida), retorno NULL para sinalizar isso. Isso ocorre porque quero que a computação termine normalmente e me diga que a função que solicitei não está definida nas entradas fornecidas. O uso, por exemplo, de uma string vazia como valor de retorno é ambíguo, pois pode ser que a função esteja definida nas entradas e a string vazia seja o resultado correto.

Eu acho que a verificação extra para um ponteiro NULL no código de chamada é necessária porque você está aplicando uma função parcial e é tarefa do método chamado informar se a função não está definida para a entrada especificada.

Prefiro usar exceções para erros que não permitem realizar o cálculo (ou seja, não foi possível encontrar nenhuma resposta).

Por exemplo, suponha que eu tenha uma classe Customer e queira implementar um método

Customer findCustomer(String customerCode)

para procurar um cliente no banco de dados do aplicativo por seu código. Nesse método, eu

  • Retorne um objeto da classe Customer se a consulta for bem-sucedida,
  • Retorne nulo se a consulta não encontrar nenhum cliente.
  • Lance uma exceção se não for possível conectar-se ao banco de dados.

As verificações extras para nulo, por exemplo

Customer customer = findCustomer("...");
if (customer != null && customer.getOrders() > 0)
{
    ...
}

fazem parte da semântica do que estou fazendo e não apenas os "pulo" para tornar o código melhor lido. Não acho que seja uma boa prática simplificar a semântica do problema em questão apenas para simplificar o código.

Obviamente, como a verificação de nulo ocorre com muita frequência, é bom que o idioma suporte alguma sintaxe especial para ele.

Também consideraria usar o padrão Null Object (como sugerido por Laf), desde que eu possa distinguir o objeto nulo de uma classe de todos os outros objetos.

Giorgio
fonte
0

Os métodos que retornam coleções devem retornar vazios, mas outros podem retornar nulos, porque, para as coleções, pode acontecer que você tenha um objeto, mas não haja elementos nele; portanto, o chamador validará apenas o tamanho e os dois.

Phani
fonte
0

Para mim, existem dois casos aqui. Se você estiver retornando algum tipo de lista, sempre a retorne, não importa o quê, vazia se não tiver nada para colocar nela.

O único caso em que vejo algum debate é quando você retorna um único item. Eu me pego preferindo retornar nulo em caso de falha em tal situação, com base em fazer as coisas falharem rapidamente.

Se você retornar um objeto nulo e o chamador precisar de um objeto real, eles poderão prosseguir e tentar usar o objeto nulo produzindo um comportamento inesperado. Eu acho que é melhor para a rotina crescer, se eles esquecerem de lidar com a situação. Se algo estiver errado, quero uma exceção o mais rápido possível. É menos provável que você envie um bug dessa maneira.

Loren Pechtel
fonte
0

Adicionando o que as pessoas já disseram sobre o Maybeconstrutor de tipos:

Outro grande ganho, além de não arriscar as NPEs, é o semântico. No mundo funcional, onde lidamos com funções puras, gostamos de tentar criar funções que, quando aplicadas, são exatamente equivalentes ao seu valor de retorno . Considere o caso de String.reverse(): Esta é uma função que, dada uma determinada string, representa a versão invertida dessa string. Sabemos que essa string existe, porque cada string pode ser revertida (strings são basicamente conjuntos de caracteres ordenados).

Agora que tal findCustomer(int id)? Esta função representa o cliente que possui o ID fornecido. Isso é algo que pode ou não existir. Mas lembre-se, as funções têm um único valor de retorno; portanto, você não pode realmente dizer "essa função retorna um cliente com o ID especificado OU retorna null.

Este é o meu principal problema ao retornar nulle retornar um objeto nulo. Eles são enganosos. nullnão é um cliente e também não é "a ausência de um cliente". É a ausência de QUALQUER COISA. É apenas um ponteiro sem letra para NADA. Nível muito baixo, feio e propenso a erros. Um objeto nulo também é bastante enganador aqui, eu acho. Um cliente nulo É um cliente. Não é a ausência de um, não é o cliente com o ID solicitado, portanto, devolvê-lo é simplesmente ERRADO. Este NÃO é o cliente que solicitei, mas você ainda afirma que retornou um cliente. Ele tem o ID errado, claramente isso é um bug. Ele quebra o contrato sugerido pelo nome e assinatura do método. Requer que o código do cliente assuma coisas sobre seu design ou leia a documentação.

Ambos os problemas são resolvidos por a Maybe Customer. De repente, não estamos dizendo "esta função representa o cliente com o ID fornecido". Estamos dizendo que "essa função representa o cliente com o ID fornecido, se ele existir . Agora, é muito claro e explícito sobre o que ele faz. Se você solicitar um cliente com um ID inexistente, receberá Nothing. Como isso é melhor que null? não apenas para o risco NPE. Mas também porque o tipo de Nothingnão é só Maybe. é Maybe Customer. Ele tem significado semântico. Ele especificamente significa "a ausência de um cliente", indicando que tal cliente não existe.

Outro problema com null é, obviamente, que é ambíguo. Será que você não encontrou o cliente ou houve um erro de conexão de banco de dados ou simplesmente não tenho permissão para vê-lo?

Se você tiver vários casos de erro como esse para tratar, poderá lançar exceções para essas versões ou (e eu prefiro dessa maneira) retornar um Either CustomerLoadError Customer, representando algo que deu errado ou o cliente retornado. Ele tem todas as vantagens de Maybe Customerpermitir que você especifique o que pode dar errado.

A principal coisa que procuro é capturar o contrato da função em sua assinatura. Não assuma as coisas, não confie em convenções passageiras, seja explícito.

sara
fonte
0

1) Se a semântica da função é que ela não pode retornar nada, o chamador DEVE testá-la, caso contrário ele irá, por exemplo. Pegue seu dinheiro e não entregue a ninguém.

2) É bom criar funções que sempre semanticamente retornam algo (ou jogam).

Com um criador de logs , faz sentido retornar o criador de logs que não registra se nenhum criador de logs foi definido. Ao retornar a coleção, quase nunca faz sentido (exceto em "nível baixo o suficiente", em que a própria coleção é os dados, e não o que ela contém) para retornar nada, porque um conjunto vazio é um conjunto, não nada.

Com uma pessoa exemplo, eu iria "hibernação" caminho (ficar vs carga, IIRC, mas não é complicado por objetos de proxy para o carregamento lento) de ter duas funções, que retorna nulo e segundo que joga.

user470365
fonte
-1
  • NULL deve ser retornado se o aplicativo espera que um dado esteja disponível, mas ele não esteja disponível. Por exemplo, um serviço que retorna a CITY com base no CEP deve retornar nulo se a cidade não for encontrada. O chamador pode então decidir lidar com o nulo ou explodir.

  • A lista vazia deve ser retornada se houver duas possibilidades. Dados disponíveis ou NÃO há dados disponíveis. Por exemplo, um serviço que retorna a (s) CIDADE (s) se a população for maior que determinado número. Ele pode retornar uma lista vazia se Nenhum dado satisfizer os critérios fornecidos.

java_mouse
fonte
-2

Retornar NULL é um design terrível , no mundo orientado a objetos. Em poucas palavras, o uso NULL leva a:

  • tratamento ad-hoc de erros (em vez de exceções)
  • semântica ambígua
  • lento em vez de rápido falhar
  • pensamento de computador vs. pensamento de objeto
  • objetos mutáveis ​​e incompletos

Verifique esta publicação no blog para obter uma explicação detalhada: http://www.yegor256.com/2014/05/13/why-null-is-bad.html

yegor256
fonte