null
O uso depende do aplicativo / idioma
Por fim, a escolha de usar ou não null
como um valor válido de aplicativo é amplamente determinada por seu aplicativo e linguagem de programação / interface / borda.
Em um nível fundamental, recomendo tentar usar tipos distintos se houver classes distintas de valores. null
pode ser uma opção se sua interface permitir e houver apenas duas classes de uma propriedade que você está tentando representar. Omitir uma propriedade pode ser uma opção se sua interface ou formato permitir. Um novo tipo agregado (classe, objeto, tipo de mensagem) pode ser outra opção.
Para o seu exemplo de string, se isso estiver na linguagem de programação, eu me faria algumas perguntas.
- Planejo adicionar futuros tipos de valores? Nesse caso,
Option
provavelmente será melhor para o seu design de interface.
- Quando preciso validar as ligações dos consumidores? Estatisticamente? Dinamicamente? Antes? Depois de? Em absoluto? Se sua linguagem de programação suportar, use os benefícios da digitação estática, pois evita a quantidade de código que você precisa criar para validação.
Option
provavelmente preenche esse caso melhor se sua sequência não for anulável. No entanto, você provavelmente terá que verificar a entrada do usuário para obter um null
valor de string de qualquer maneira, portanto, provavelmente eu voltaria para a primeira linha de questionamento: quantos tipos de valores quero / quero representar.
- É
null
indicativo de um erro do programador na minha linguagem de programação? Infelizmente, null
geralmente é o valor padrão para referências ou ponteiros não inicializados (ou não explicitamente inicializados) em alguns idiomas. O null
valor é aceitável como o valor padrão? É seguro como um valor padrão? Às vezes null
é indicativo de valores desalocados. Devo fornecer aos consumidores da minha interface uma indicação desses possíveis problemas de gerenciamento de memória ou inicialização no programa deles? Qual é o modo de falha de uma chamada em face desses problemas? O chamador está no mesmo processo ou thread que o meu para que esses erros sejam um alto risco para o meu aplicativo?
Dependendo das suas respostas a essas perguntas, você provavelmente poderá saber se null
é ou não adequado para sua interface.
Exemplo 1
- Sua aplicação é essencial para a segurança
- Você está usando algum tipo de inicialização de heap na inicialização e
null
é um possível valor de sequência passado após falha ao alocar espaço para uma sequência.
- Existe um potencial em que essa string atinge sua interface
Resposta: null
provavelmente não é apropriado
Justificação: null
neste caso, é realmente usado para indicar dois tipos diferentes de valores. O primeiro pode ser um valor padrão que o usuário da sua interface pode querer definir. Infelizmente, o segundo valor é um sinalizador para indicar que seu sistema não está funcionando corretamente. Nesses casos, você provavelmente deseja falhar o mais seguro possível (o que isso significa para o seu sistema).
Exemplo 2
- Você está usando uma estrutura C que possui um
char *
membro.
- Seu sistema não usa alocação de heap e você está usando a verificação MISRA.
- Sua interface aceita essa estrutura como um ponteiro e verifica se a estrutura não aponta para
NULL
- O valor padrão e seguro do
char *
membro para sua API pode ser indicado por um único valor deNULL
- Após a inicialização da estrutura do usuário, você gostaria de fornecer ao usuário a possibilidade de não inicializar explicitamente o
char *
membro.
Resposta: NULL
pode ser apropriado
Fundamentação da petição: Há uma pequena chance de que sua estrutura passe na NULL
verificação, mas não foi inicializada. No entanto, sua API pode não ser capaz de explicar isso, a menos que você tenha algum tipo de soma de verificação no valor da estrutura e / ou verificação de intervalo do endereço da estrutura. Os linters MISRA-C podem ajudar os usuários da sua API sinalizando o uso de estruturas antes da inicialização. No entanto, quanto ao char *
membro, se o ponteiro para estrutura apontar para uma estrutura inicializada, NULL
é o valor padrão de um membro não especificado em um inicializador de estrutura. Portanto, NULL
pode servir como um valor padrão seguro para o char *
membro struct em seu aplicativo.
Se estiver em uma interface de serialização, eu me perguntaria as seguintes perguntas sobre se deve ou não usar nulo em uma string.
- É
null
indicativo de um possível erro do lado do cliente? Para JSON em JavaScript, esse provavelmente é um não, pois null
não é necessariamente usado como uma indicação de falha na alocação. Em JavaScript, é usado como uma indicação explícita da ausência do objeto em uma referência a ser configurada problemática. No entanto, existem analisadores e serializadores não-javascript que mapeiam JSON null
para o null
tipo nativo . Se for esse o caso, isso implica na discussão sobre se o null
uso nativo é ou não adequado para sua combinação específica de idioma, analisador e serializador.
- A ausência explícita de um valor de propriedade afeta mais do que um único valor de propriedade? Às vezes, a
null
indica realmente que você tem um novo tipo de mensagem inteiramente. Pode ser mais limpo para seus consumidores do formato de serialização especificar apenas um tipo de mensagem completamente diferente. Isso garante que a validação e a lógica do aplicativo possam ter uma separação limpa entre as duas distinções de mensagens que sua interface da web fornece.
Conselho Geral
null
não pode ser um valor em uma borda ou interface que não o suporte. Se você estiver usando algo de natureza extremamente flexível na digitação de valores de propriedades (por exemplo, JSON), tente inserir alguma forma de esquema ou validação no software de borda do consumidor (por exemplo, JSON Schema ), se puder. Se for uma API da linguagem de programação, valide a entrada do usuário estaticamente, se possível (por meio de digitação) ou o mais alto possível em tempo de execução (também conhecido como prática de programação defensiva nas interfaces voltadas ao consumidor). O mais importante é documentar ou definir a borda, para que não haja dúvidas sobre:
- Que tipo de valor uma determinada propriedade aceita
- Quais faixas de valor são válidas para uma determinada propriedade.
- Como um tipo agregado deve ser estruturado. Quais propriedades devem / devem / podem estar presentes em um tipo agregado?
- Se for algum tipo de contêiner, quantos itens podem ou devem conter e quais são os tipos de valores que o contêiner contém?
- Em que ordem, se houver, são devolvidas propriedades ou instâncias de um tipo de contêiner ou agregados?
- Que efeitos colaterais existem na definição de valores específicos e quais são os efeitos colaterais da leitura desses valores?