null
El uso depende de la aplicación / idioma
En última instancia, la elección de usar o no null
un valor de aplicación válido depende en gran medida de su aplicación y lenguaje de programación / interfaz / edge.
En un nivel fundamental, recomendaría tratar de usar tipos distintos si hay clases distintas de valores. null
puede ser una opción si su interfaz lo permite y solo hay dos clases de una propiedad que está tratando de representar. Omitir una propiedad puede ser una opción si su interfaz o formato lo permite. Un nuevo tipo agregado (clase, objeto, tipo de mensaje) puede ser otra opción.
Para su ejemplo de cadena, si esto está en el lenguaje de programación, me haría un par de preguntas.
- ¿Planeo agregar futuros tipos de valores? Si es así,
Option
probablemente será mejor para el diseño de su interfaz.
- ¿Cuándo necesito validar las llamadas de los consumidores? ¿Inactivamente? ¿Dinamicamente? ¿Antes de? ¿Después? ¿En absoluto? Si su lenguaje de programación lo admite, use los beneficios de la escritura estática, ya que evita la cantidad de código que debe crear para la validación.
Option
probablemente llene este caso mejor si su cadena no es anulable. Sin embargo, es probable que tenga que verificar la entrada del usuario para un null
valor de cadena de todos modos, por lo que probablemente diferiré de nuevo a la primera línea de preguntas: cuántos tipos de valores quiero / quiero representar.
- ¿Es
null
indicativo de un error del programador en mi lenguaje de programación? Desafortunadamente, a null
menudo es el valor predeterminado para punteros o referencias no inicializados (o no inicializados explícitamente) en algunos idiomas. ¿Es null
un valor aceptable como valor predeterminado? ¿Es seguro como valor predeterminado? A veces null
es indicativo de valores desasignados. ¿Debo proporcionar a los consumidores de mi interfaz una indicación de estos posibles problemas de administración de memoria o inicialización en su programa? ¿Cuál es el modo de falla de tal llamada ante tales problemas? ¿La persona que llama está en el mismo proceso o hilo que el mío, de modo que tales errores son un riesgo alto para mi aplicación?
Dependiendo de sus respuestas a estas preguntas, probablemente podrá centrarse en si es o no null
adecuado para su interfaz.
Ejemplo 1
- Su aplicación es crítica para la seguridad.
- Está utilizando algún tipo de inicialización de montón en el inicio y
null
es un posible valor de cadena que se devuelve al no poder asignar espacio para una cadena.
- Existe la posibilidad de que una cadena llegue a su interfaz
Respuesta: null
probablemente no sea apropiado
Justificación: null
en este caso, en realidad se usa para indicar dos tipos diferentes de valores. El primero puede ser un valor predeterminado que el usuario de su interfaz puede establecer. Desafortunadamente, el segundo valor es un indicador para indicar que su sistema no funciona correctamente. En tales casos, probablemente desee fallar de la manera más segura posible (lo que sea que eso signifique para su sistema).
Ejemplo 2
- Estás utilizando una estructura C que tiene un
char *
miembro.
- Su sistema no utiliza la asignación de almacenamiento dinámico y está utilizando la verificación MISRA.
- Su interfaz acepta esta estructura como un puntero y verifica para asegurarse de que la estructura no apunta a
NULL
- El valor predeterminado y seguro del
char *
miembro para su API se puede indicar mediante un solo valor deNULL
- Tras la inicialización de la estructura de su usuario, le gustaría brindarle al usuario la posibilidad de no inicializar explícitamente al
char *
miembro.
Respuesta: NULL
puede ser apropiado
Justificación: existe una pequeña posibilidad de que su estructura pase la NULL
verificación pero no se haya inicializado. Sin embargo, es posible que su API no pueda dar cuenta de esto a menos que tenga algún tipo de suma de verificación en el valor de estructura y / o la comprobación de rango de la dirección de la estructura. Las listas MISRA-C pueden ayudar a los usuarios de su API marcando el uso de estructuras antes de su inicialización. Sin embargo, en cuanto al char *
miembro, si el puntero a estructura apunta a una estructura inicializada, NULL
es el valor predeterminado de un miembro no especificado en un inicializador de estructura. Por lo tanto, NULL
puede servir como un valor predeterminado seguro para el char *
miembro de estructura en su aplicación.
Si está en una interfaz de serialización, me haría las siguientes preguntas sobre si usar o no nulo en una cadena.
- ¿Es
null
indicativo de un posible error del lado del cliente? Para JSON en JavaScript, este es probablemente un no, ya null
que no se usa necesariamente como una indicación de falla de asignación. En JavaScript, se utiliza como una indicación explícita de la ausencia de objetos de una referencia que se establece de forma problemática. Sin embargo, existen analizadores y serializadores que no son JavaScript que asignan JSON null
al null
tipo nativo . Si este es el caso, se inicia la discusión sobre si el null
uso nativo es adecuado para su combinación particular de idioma, analizador y serializador.
- ¿La ausencia explícita de un valor de propiedad impacta más que un solo valor de propiedad? A veces, a en
null
realidad indica que tiene un nuevo tipo de mensaje por completo. Puede ser más limpio para sus consumidores el formato de serialización simplemente especificar un tipo de mensaje completamente diferente. Esto garantiza que su validación y lógica de aplicación puedan tener una separación clara entre las dos distinciones de mensajes que proporciona su interfaz web.
Consejo general
null
no puede ser un valor en un borde o interfaz que no lo admite. Si está utilizando algo que es extremadamente suelto en la tipificación de valores de propiedades (es decir, JSON), intente introducir alguna forma de esquema o validación en el software de borde de los consumidores (por ejemplo, Esquema JSON ) si puede. Si se trata de una API de lenguaje de programación, valide la entrada del usuario de forma estática si es posible (a través de la escritura) o tan fuerte como sea razonable en tiempo de ejecución (también conocido como practicar la programación defensiva en interfaces orientadas al consumidor). Lo que es más importante, documente o defina el borde para que no haya dudas en cuanto a:
- Qué tipo (s) de valor acepta una propiedad determinada
- Qué rangos de valor son válidos para una propiedad determinada.
- Cómo se debe estructurar un tipo agregado. ¿Qué propiedades deben / deberían / pueden estar presentes en un tipo agregado?
- Si se trata de algún tipo de contenedor, ¿cuántos elementos pueden o deben contener el contenedor y cuáles son los tipos de valores que contiene el contenedor?
- ¿Qué orden, si corresponde, son las propiedades o instancias de un tipo de contenedor o agregado devuelto?
- ¿Qué efectos secundarios existen al establecer valores particulares y cuáles son los efectos secundarios de leer esos valores?