Comentarios de código limpio vs documentación de clase

83

Estoy teniendo algunas conversaciones con mis nuevos colegas sobre los comentarios. A ambos nos gusta Clean Code , y estoy perfectamente de acuerdo con el hecho de que los comentarios de código en línea deben evitarse y que los nombres de clase y métodos deben usarse para expresar lo que hacen.

Sin embargo, soy un gran admirador de agregar pequeños resúmenes de clase que intentan explicar el propósito de la clase y lo que realmente representa, principalmente para que sea fácil mantener el patrón del principio de responsabilidad única . También estoy acostumbrado a agregar resúmenes de una línea a los métodos que explican qué debe hacer el método. Un ejemplo típico es el método simple.

public Product GetById(int productId) {...}

Estoy agregando el siguiente resumen del método

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary

Creo que el hecho de que el método devuelve nulo debe documentarse. Un desarrollador que quiera llamar a un método no debería tener que abrir mi código para ver si el método devuelve nulo o produce una excepción. A veces es parte de una interfaz, por lo que el desarrollador ni siquiera sabe qué código subyacente se está ejecutando.

Sin embargo, mis colegas piensan que este tipo de comentarios son " olor a código " y que "los comentarios son siempre fracasos" ( Robert C. Martin ).

¿Hay alguna manera de expresar y comunicar este tipo de conocimiento sin agregar comentarios? Como soy un gran admirador de Robert C. Martin, me estoy confundiendo un poco. ¿Los resúmenes son lo mismo que los comentarios y, por lo tanto, siempre fallan?

No se trata de comentarios en línea.

Bjorn
fuente
38
Robert Martin dijo "¿Los comentarios son siempre fracasos"? Bueno, entonces es un extremista marginal, y debe tomarse con una pizca de sal. (Sí, soy consciente de que escribe así con fines retóricos, para transmitir su mensaje. Mi punto es, tú también deberías ).
Kilian Foth
18
Los libros del tío Bob deberían venir con una bolsa de sal de 1 kg ...
AK_
66
Si sigue a Robert Martin, la documentación para el caso nulo debería ser una prueba. Es decir, debe tener una prueba que muestre en qué caso el método puede devolver nulo. Alternativamente, dado que esto es Java, una anotación @Nullable también sería mejor que el comentario.
Martin Epsz
15
@Bjorn Soy dueño de una copia de Clean Code y la he leído de principio a fin más de una vez. Sí, el tío Bob prefiere que el código sea autodocumentado, pero hay varios ejemplos de comentarios en su propio código en el libro . El punto es que si se siente obligado a escribir un comentario, intente realmente cambiar el código en lugar de agregar el comentario, pero no rechace los comentarios por completo (incluso los comentarios en línea).
66
El método debería llamarse TryGetById y el comentario debería eliminarse.
usr

Respuestas:

116

Como han dicho otros, hay una diferencia entre los comentarios de documentación de API y los comentarios en línea. Desde mi punto de vista, la principal diferencia es que se lee un comentario en línea junto con el código , mientras que un comentario de documentación se lee junto con la firma de lo que sea que esté comentando.

Dado esto, podemos aplicar el mismo principio DRY . ¿El comentario dice lo mismo que la firma? Veamos tu ejemplo:

Recupera un producto por su id.

Esta parte solo repite lo que ya vemos del nombre GetByIdmás el tipo de retorno Product. También plantea la pregunta de cuál es la diferencia entre "obtener" y "recuperar", y cuál es el código de soporte versus el comentario sobre esa distinción. Entonces es innecesario y un poco confuso. En todo caso, se interpone en el camino de la segunda parte del comentario realmente útil:

devuelve nulo si no se encontró ningún producto.

Ah! Eso es algo que definitivamente no podemos saber con certeza solo por la firma, y ​​proporciona información útil.


Ahora lleva esto un paso más allá. Cuando la gente habla de comentarios como olores de código, la pregunta no es si el código tal como es necesita un comentario, sino si el comentario indica que el código podría escribirse mejor, para expresar la información en el comentario. Eso es lo que significa "olor a código": no significa "¡no hagas esto!", Significa "si estás haciendo esto, podría ser una señal de que hay un problema".

Entonces, si sus colegas le dicen que este comentario sobre nulo es un olor a código, simplemente debe preguntarles: "Bien, ¿cómo debo expresar esto entonces?" Si tienen una respuesta factible, has aprendido algo. Si no es así, probablemente matará sus quejas muertas.


Con respecto a este caso específico, generalmente se sabe que el problema nulo es difícil. Hay una razón por la cual las bases de códigos están llenas de cláusulas de protección, por qué los cheques nulos son una precondición popular para los contratos de códigos, por qué la existencia de nulos se ha llamado un "error de mil millones de dólares". No hay tantas opciones viables. Sin embargo, uno popular que se encuentra en C # es la Try...convención:

public bool TryGetById(int productId, out Product product);

En otros idiomas, puede ser idiomático usar un tipo (a menudo llamado algo así como Optionalo Maybe) para indicar un resultado que puede o no estar allí:

public Optional<Product> GetById(int productId);

Entonces, en cierto modo, esta postura anti-comentario nos ha llevado a alguna parte: al menos hemos pensado si este comentario representa un olor y qué alternativas podrían existir para nosotros.

Si realmente deberíamos preferirlos a la firma original es otro debate, pero al menos tenemos opciones para expresar a través del código en lugar de comentar lo que sucede cuando no se encuentra ningún producto. Debes discutir con tus colegas cuál de estas opciones piensan que es mejor y por qué, y con suerte ayudar a avanzar más allá de las declaraciones dogmáticas generales sobre los comentarios.

Ben Aaronson
fuente
99
O el Linqequivalente de Try..., ...OrDefaultque se devuelve default(T)si la cláusula llevaría a un resultado vacío.
Bart van Nierop
44
Realmente aprecio su distinción entre comentarios de código en línea y comentarios de documentación, y los ejemplos dados :)
Rachel
2
Los posibles valores de retorno de una función deben ser evidentes por su firma. El TryGetValuepatrón es una forma razonable de hacer esto en C #, pero la mayoría de los lenguajes funcionales tienen una mejor manera de representar un valor perdido. Lea más aquí
AlexFoxGill
2
@BenAaronson: si se quiere tener una interfaz genérica que admita la covarianza, se puede usar T TryGetValue(params, ref bool success)para cualquier tipo T o T TryGetValue(params), con nulo que indica falla, para el tipo T con restricción de clase, pero el TryGetXXpatrón que devuelve booles incompatible con la covarianza.
supercat
66
En Java 8, puede devolver un Optional<Product>para indicar que puede que no haya un Producto devuelto por el método.
Wim Deblauwe
102

La cita de Robert C. Martin está fuera de contexto. Aquí está la cita con un poco más de contexto:

Nada puede ser tan útil como un comentario bien colocado. Nada puede abarrotar un módulo más que los frívolos comentarios dogmáticos. Nada puede ser tan perjudicial como un viejo comentario grosero que propaga mentiras y desinformación.

Los comentarios no son como la Lista de Schindler. No son "puro bien". De hecho, los comentarios son, en el mejor de los casos, un mal necesario. Si nuestros lenguajes de programación fueran lo suficientemente expresivos, o si tuviéramos el talento de utilizar sutilmente esos lenguajes para expresar nuestra intención, no necesitaríamos muchos comentarios, tal vez en absoluto.

El uso adecuado de los comentarios es para compensar nuestra falta de expresión en código. Tenga en cuenta que usé la palabra fracaso. Lo dije en serio. Los comentarios son siempre fracasos. Debemos tenerlos porque no siempre podemos descubrir cómo expresarnos sin ellos, pero su uso no es motivo de celebración.

Entonces, cuando se encuentre en una posición en la que necesite escribir un comentario, piénselo bien y vea si no hay alguna forma de cambiar las tornas y expresarse en código. Cada vez que te expreses en código, debes darte palmaditas en la espalda. Cada vez que escribe un comentario, debe hacer una mueca y sentir el fracaso de su capacidad de expresión.

(Copiado de aquí , pero la cita original es de Clean Code: A Handbook of Agile Software Craftsmanship )

La forma en que esta cita se reduce a "Los comentarios son siempre fracasos" es un buen ejemplo de cómo algunas personas tomarán una cita sensata fuera de contexto y la convertirán en un estúpido dogma.


Documentación de la API (como javadoc) se supone que documentar la API para que el usuario pueda utilizarlo sin tener que leer el código fuente . Entonces, en este caso, la documentación debe explicar lo que hace el método. Ahora puede argumentar que "Recupera un producto por su id" es redundante porque ya está indicado por el nombre del método, pero la información que nullpuede devolverse es definitivamente importante para documentar, ya que esto no es obvio de ninguna manera.

Si desea evitar la necesidad del comentario, debe eliminar el problema subyacente (que es el uso nullcomo un valor de retorno válido), haciendo que la API sea más explícita. Por ejemplo, podría devolver algún tipo de Option<Product>tipo, por lo que la firma del tipo en sí comunica claramente lo que se devolverá en caso de que no se encuentre el producto.

Pero, en cualquier caso, no es realista documentar una API completamente solo a través de nombres de métodos y firmas de tipo. Use doc-comments para cualquier información adicional no obvia que el usuario debe saber. Tomemos como ejemplo la documentación de la API de DateTime.AddMonths()BCL:

El método AddMonths calcula el mes y año resultantes, teniendo en cuenta los años bisiestos y el número de días en un mes, luego ajusta la parte del día del objeto DateTime resultante. Si el día resultante no es un día válido en el mes resultante, se utiliza el último día válido del mes resultante. Por ejemplo, 31 de marzo + 1 mes = 30 de abril. La parte de la hora del día del objeto DateTime resultante permanece igual que esta instancia.

¡No hay forma de que puedas expresar esto usando solo el nombre y la firma del método! Por supuesto, la documentación de su clase puede no requerir este nivel de detalle, es solo un ejemplo.


Los comentarios en línea tampoco son malos.

Los malos comentarios son malos. Por ejemplo, comentarios que solo explican lo que se puede ver trivialmente del código, el ejemplo clásico es:

// increment x by one
x++;

Los comentarios que explican algo que podría aclararse cambiando el nombre de una variable o método o reestructurando el código, es un olor a código:

// data1 is the collection of tasks which failed during execution
var data1 = getData1();

Este es el tipo de comentarios que Martin critica. El comentario es un síntoma de una falla al escribir código claro, en este caso para usar nombres que se explican por sí mismos para variables y métodos. Por supuesto, el comentario en sí no es el problema, el problema es que necesitamos el comentario para comprender el código.

Pero los comentarios deben usarse para explicar todo lo que no es obvio en el código, por ejemplo, por qué el código está escrito de cierta manera no obvia:

// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();

Los comentarios que explican lo que hace una pieza de código demasiado complicada también es un olor, pero la solución no es prohibir los comentarios, ¡la solución es arreglar el código! En la palabra real, el código complicado ocurre (con suerte solo temporalmente hasta un refactorizador) pero ningún desarrollador ordinario escribe código limpio perfecto la primera vez. Cuando ocurre un código complicado, es mucho mejor escribir un comentario explicando lo que hace que no escribir un comentario. Este comentario también facilitará la refactorización posterior.

A veces el código es inevitablemente complejo. Puede ser un algoritmo complicado, o puede ser un código que sacrifica la claridad por razones de rendimiento. De nuevo los comentarios son necesarios.

JacquesB
fuente
13
También está el caso en el que su código maneja una situación que es complicada, y ningún código simple puede manejarlo.
gnasher729
66
Buen punto, gnasher. Esto parece suceder a menudo cuando tiene que optimizar algún fragmento de código para el rendimiento.
JacquesB
99
Incluso un comentario x++puede ser bueno si es algo así como "incrementar x en uno, envolviendo si es UINT32_MAX"; cualquiera que conozca la especificación del lenguaje sabría que incrementar un uint32_tajuste de voluntad, pero sin el comentario, uno podría no saber si dicho ajuste era una parte esperada del algoritmo que se está implementando.
supercat
55
@ l0b0: ¡espero que estés bromeando!
JacquesB
99
@ l0b0 No existe el código temporal. El código nunca se refactoriza porque la empresa estaba contenta con el resultado y no aprobará fondos para arreglarlo. Dentro de cinco años, algún desarrollador junior verá este código, ya ni siquiera está usando WizBug 4.0 ya que lo reemplazó con Bugtrocity v9, por lo que "Bug123" no significa nada para él. Ahora piensa que así es como se supone que debe ser el código permanente, y continúa siendo un desarrollador terrible durante toda su carrera. Piensa en los niños. No escribas código temporal.
corsiKa
36

Hay una diferencia entre comentar su código y documentar su código .

  • Se necesitan comentarios para mantener el código más adelante, es decir, cambiar el código en sí.

    Los comentarios pueden ser percibidos como problemáticos. El punto extremo sería decir que siempre indican un problema, ya sea dentro de su código (código demasiado difícil de entender) o dentro del idioma (idioma que no puede ser lo suficientemente expresivo; por ejemplo, el hecho de que el método nunca regrese nullpodría expresarse a través de contratos de código en C #, pero no hay forma de expresarlo a través de código en, digamos, PHP

  • Se necesita documentación para poder utilizar los objetos (clases, interfaces) que desarrolló. El público objetivo es diferente: no se trata de las personas que mantendrán su código y lo cambiarán de lo que estamos hablando aquí, sino de las personas que apenas necesitan usarlo .

    Eliminar la documentación porque el código es lo suficientemente claro es una locura, ya que la documentación está aquí específicamente para permitir el uso de clases e interfaces sin tener que leer miles de líneas de código .

Arseni Mourzenko
fuente
Sí, pero al menos parte del punto de Martin es que con las prácticas de desarrollo modernas, las pruebas son la documentación, no el código en sí. Asumiendo que el código se está probando con un sistema de prueba de estilo BDD, por ejemplo, el flujo de especificación, las pruebas en sí mismas son una descripción directamente legible del comportamiento del método ("dada una base de datos de productos cuando se llama a GetById con la identificación de un producto válido en ese momento el objeto apropiado del Producto se devuelve [...] cuando se llama a GetById con una identificación de producto no válida y luego se devuelve nulo "o algo así).
Julio
13

Bueno, parece que su colega lee libros, capta lo que dicen y aplica lo que aprendió sin pensar y sin tener en cuenta el contexto.

Su comentario sobre lo que hace la función debe ser tal que pueda tirar el código de implementación, leo el comentario de la función y puedo escribir el reemplazo para la implementación, sin que nada salga mal.

Si el comentario no me dice si se produce una excepción o si se devuelve nil, no puedo hacer eso. Por otra parte, si el comentario no le dice que si se produce una excepción o si se devuelve nil, entonces siempre se llama a la función, debe asegurarse de que su código funciona correctamente si se produce una excepción o se devuelve nulo.

Entonces tu colega está totalmente equivocado. Y sigue leyendo todos los libros, pero piensa por ti mismo.

PD. Vi su línea "a veces es parte de una interfaz, por lo que ni siquiera sabe qué código se está ejecutando". Incluso con funciones virtuales, no sabe qué código se está ejecutando. Peor aún, si escribiste una clase abstracta, ¡ni siquiera hay ningún código! Entonces, si tiene una clase abstracta con una función abstracta, los comentarios que agrega a la función abstracta son lo único que un implementador de una clase concreta tiene que guiarlos. Esos comentarios también pueden ser lo único que puede guiar a un usuario de la clase, por ejemplo, si todo lo que tiene es una clase abstracta y una fábrica que devuelve una implementación concreta, pero nunca ve ningún código fuente de la implementación. (Y, por supuesto, no debería mirar el código fuente de una implementación).

gnasher729
fuente
No he comentado el código en 10 años. Los comentarios son hinchazón, basura. Nadie comenta el código en estos días. Nos enfocamos en código bien formado y con nombre, módulos pequeños, desacoplamiento, etc. ESO hace que su código sea legible, no comentarios. Las pruebas aseguran que si descarta el código, que nada salga mal, que no haya comentarios. Las pruebas le dicen cómo usa el código que escribe, cómo los llama y por qué están allí en primer lugar. Eres demasiado viejo de la escuela, necesitas aprender sobre las pruebas y limpiar el código, amigo.
PositiveGuy
12

Hay dos tipos de comentarios a tener en cuenta: aquellos visibles para las personas con el código y aquellos utilizados para generar documentación.

El tipo de comentario al que se refiere el tío Bob es el tipo que solo es visible para las personas con el código. Lo que él defiende es una forma de SECO . Para una persona que está mirando el código fuente, el código fuente debe ser la documentación que necesita. Incluso en el caso de que las personas tengan acceso al código fuente, los comentarios no siempre son malos. A veces, los algoritmos son complicados o necesita capturar por qué está tomando un enfoque no obvio para que otros no terminen rompiendo su código si intentan corregir un error o agregar una nueva característica.

Los comentarios que está describiendo son documentación de la API. Estas son cosas que son visibles para las personas que usan su implementación, pero que pueden no tener acceso a su código fuente. Incluso si tienen acceso a su código fuente, pueden estar trabajando en otros módulos y no estar viendo su código fuente. Estas personas encontrarían útil tener esta documentación disponible en su IDE mientras escriben su código.

Thomas Owens
fuente
Sinceramente, nunca pensé en DRY aplicando a los comentarios de código +, pero tiene mucho sentido. Algo así como el ejemplo de "incremento X" en la respuesta de @ JacquesB.
7

El valor de un comentario se mide en el valor de la información que proporciona menos el esfuerzo necesario para leerlo y / o ignorarlo. Entonces si analizamos el comentario

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary>

Por valor y costo, vemos tres cosas:

  1. Retrieves a product by its idrepite lo que dice el nombre de la función, por lo que es un costo sin valor. Debería ser eliminado.

  2. returns null if no product was foundEs una información muy valiosa. Es probable que reduzca los tiempos que otros codificadores tendrán que analizar la implementación de la función. Estoy bastante seguro de que ahorra más lectura que el costo de lectura que presenta. Debería quedarse.

  3. Las líneas

    /// <summary>
    /// </summary>
    

    No llevar información alguna. Son puro costo para el lector del comentario. Pueden estar justificados si su generador de documentación los necesita, pero en ese caso probablemente debería pensar en un generador de documentación diferente.

    Esta es la razón por la cual el uso de generadores de documentación es una idea discutible: generalmente requieren muchos comentarios adicionales que no contienen información o repiten cosas obvias, solo por el bien de un documento pulido.


Una observación que no he encontrado en ninguna de las otras respuestas:

Incluso los comentarios que no son necesarios para comprender / usar el código pueden ser muy valiosos. Aquí hay uno de esos ejemplos:

//XXX: The obvious way to do this would have been ...
//     However, since we need this functionality primarily for ...
//     doing this the non-obvious way of ...
//     gives us the advantage of ...

Probablemente una gran cantidad de texto, completamente innecesario para entender / usar el código. Sin embargo, explica una razón por la cual el código se ve como se ve. Se detendrá a las personas que miran el código, se preguntan por qué no se hace de la manera obvia y comenzarán a refactorizar el código hasta que se den cuenta de por qué el código se escribió así en primer lugar. E incluso si el lector es lo suficientemente inteligente como para no saltar directamente a la refactorización, todavía necesitan descubrir por qué el código se ve como se ve antes de darse cuenta de que debería mantenerse como está. Este comentario literalmente podría ahorrarle horas de trabajo. Por lo tanto, el valor es más alto que el costo.

Del mismo modo, los comentarios pueden comunicar las intenciones de un código, en lugar de cómo funciona. Y pueden pintar el panorama general que generalmente se pierde en los detalles minuciosos del código en sí. Como tal, tienes razón al estar a favor de los comentarios de la clase. Valoro más los comentarios de clase si explican la intención de la clase, cómo interactúa con otras clases, cómo se debe usar, etc. Por desgracia, no soy un gran autor de tales comentarios ...

cmaster
fuente
2
Wow: cambie su generador de documentos porque requiere un par de líneas adicionales de html para el análisis. No vamos a.
corsiKa
2
@corsiKa YMMV, pero por mi parte preferiría un generador de documentación que reduzca al mínimo los costos en comentarios. Por supuesto, también prefiero leer un archivo de encabezado bien escrito que una documentación de doxygen que no esté sincronizada con el código real. Pero, como dije, YMMV.
cmaster
44
Incluso si el nombre de un método describe su propósito de manera brillante, repetir ese propósito usando lenguaje natural puede hacer que sea más fácil para alguien que lo lea asociar ese propósito con las advertencias que siguen. Una reexpresión de lo que se describe en el nombre será lo suficientemente breve como para que, incluso si el valor es bajo, el costo también será bajo. Por lo tanto, no estoy de acuerdo con la primera parte de tu publicación. +1, sin embargo, para la segunda parte. La documentación de enfoques alternativos que fueron evaluados y rechazados puede ser extremadamente valiosa, pero rara vez se le da la atención que merece.
supercat
GetByIdplantea la pregunta, qué es id, y también, qué obtener de dónde. El comentario de la documentación debe permitir que el entorno de desarrollo muestre la respuesta a estas preguntas. A menos que se explique en otra parte en los comentarios del documento del módulo, también sería un lugar para decir por qué uno obtendría la identificación de todos modos.
hyde
Los comentarios soplan, limpia el código (autodescriptivo), TDD (recibe comentarios a menudo y recibe comentarios sobre su diseño a menudo), y las reglas de pruebas (le dan confianza y documenta el comportamiento). PRUEBAS pruebas de personas. Un nadie aquí está hablando de eso. wake up
PositiveGuy
4

El código no comentado es un código incorrecto. Es un mito generalizado (si no universal) que el código puede leerse de la misma manera que, por ejemplo, el inglés. Debe ser interpretado, y para cualquier código que no sea el más trivial que requiere tiempo y esfuerzo. Además, todos tienen un nivel diferente de capacidad tanto para leer como para escribir cualquier idioma. Las diferencias entre el autor y los estilos y capacidades de codificación del lector son fuertes barreras para una interpretación precisa. También es un mito que puede derivar la intención del autor de la implementación del código. En mi experiencia, rara vez es incorrecto agregar comentarios adicionales.

Robert Martin y col. considérelo un "mal olor" porque puede ser que el código haya cambiado y los comentarios no. Digo que es algo bueno (exactamente de la misma manera que se agrega un "mal olor" al gas doméstico para alertar al usuario de fugas). La lectura de comentarios le brinda un punto de partida útil para interpretar el código real. Si coinciden, habrá aumentado la confianza en el código. Si difieren, entonces ha detectado un olor de advertencia y necesita investigar más a fondo. La cura para un "mal olor" no es eliminar el olor sino sellar la fuga.

Vince O'Sullivan
fuente
2
Dado que usted es un autor inteligente y el texto es para beneficio de una audiencia inteligente; Dibujas la línea usando el sentido común. Obviamente, tal como está, el ejemplo es tonto, pero eso no quiere decir que no haya una muy buena razón para aclarar con un comentario por qué el código incluye un i ++ en ese punto.
Vince O'Sullivan
8
i++; // Adjust for leap years.
Vince O'Sullivan
55
"Robert Martin et al. Lo consideran un" mal olor "porque puede ser que el código haya cambiado y los comentarios no". Eso es solo una parte del olor. Lo peor del olor proviene de la idea de que el programador decidió no intentar escribir el código de una manera más descriptiva, y en su lugar eligió "sellar la fuga" con un comentario. Su afirmación es que, en lugar de incluir un comentario de "// ajustar por años bisiestos", uno probablemente debería tener un método "ajustarForLeapYears ()" en el propio código (o algo similar). La documentación se presenta en forma de pruebas que ejercen la lógica del año bisiesto.
Eric King
3
Consideraría agregar una llamada al método para reemplazar una sola línea de código con una exageración de comentarios, particularmente porque el nombre del método es en sí mismo un comentario que etiqueta un fragmento de código y no garantiza una mejor precisión de la documentación. (Si esa línea ocurriera en dos o más lugares, la introducción de una llamada al método sería, por supuesto, la solución correcta)
Vince O'Sullivan
1
@ Jay La razón es que hacer sus abstracciones explícitas (por ejemplo, introduciendo métodos) es la regla. No hacerlo porque podría terminar con un método que tiene una línea es la excepción. Permítanme parafrasear la regla arbitraria real : "Use las estructuras de su lenguaje de programación (típicamente métodos y clases) para introducir abstracciones, a menos que la implementación de esa abstracción pueda expresarse como una línea de código, en ese caso especifique la abstracción en lenguaje natural agregando un comentario."
Eric
3

En algunos idiomas (F #, por ejemplo), todo este comentario / documentación puede expresarse en la firma del método. Esto se debe a que en F #, nulo generalmente no es un valor permitido a menos que esté específicamente permitido.

Lo que es común en F # (y también en varios otros lenguajes funcionales) es que, en lugar de nulo, utiliza un tipo de opción Option<T>que podría ser Noneo Some(T). El lenguaje entonces entendería esto y lo obligaría (o le advertirá si no lo hace) coincidir en ambos casos cuando intente usarlo.

Entonces, por ejemplo, en F #, podría tener una firma que se vea así

val GetProductById: int -> Option<Product>

Y entonces esta sería una función que toma un parámetro (un int) y luego devuelve un producto o el valor Ninguno.

Y luego podrías usarlo así

let product = GetProduct 42
match product with
| None -> printfn "No product found!"
| Some p -> DoThingWithProduct p

Y obtendría advertencias del compilador si no coincide con los dos casos posibles. Por lo tanto, no hay forma posible de obtener excepciones de referencia nula allí (a menos que ignore las advertencias del compilador, por supuesto), y sepa todo lo que necesita simplemente mirando la firma de la función.

Por supuesto, esto requiere que su lenguaje esté diseñado de esta manera, que muchos lenguajes comunes como C #, Java, C ++, etc., no tienen. Por lo tanto, esto puede no serle útil en su situación actual. Pero es (con suerte) bueno saber que existen idiomas que le permiten expresar este tipo de información de forma estática sin recurrir a comentarios, etc. :)

wasatz
fuente
1

Aquí hay algunas respuestas excelentes y no quiero repetir lo que dicen. Pero déjame agregar algunos comentarios. (Sin juego de palabras).

Hay muchas afirmaciones que hacen las personas inteligentes, sobre el desarrollo de software y muchos otros temas, supongo, que son muy buenos consejos cuando se entienden en contexto, pero qué personas tontas que toman fuera de contexto o aplican en situaciones inapropiadas o toman extremos ridículos

La idea de que el código debe autodocumentarse es una excelente idea. Pero en la vida real, hay limitaciones en la practicidad de esta idea.

Un inconveniente es que el lenguaje puede no proporcionar características para documentar lo que debe documentarse de manera clara y concisa. A medida que mejoran los lenguajes informáticos, esto se convierte en un problema cada vez menor. Pero no creo que haya desaparecido por completo. En los días en que escribí en ensamblador, tenía mucho sentido incluir un comentario como "precio total = precio de artículos no gravables más precio de artículos gravables más precio de artículos gravables * tasa impositiva". Exactamente lo que estaba en un registro en un momento dado no era necesariamente obvio. Tomó muchos pasos para hacer una operación simple. Etc. Pero si está escribiendo en un lenguaje moderno, tal comentario sería una reexpresión de una línea de código.

Siempre me molesto cuando veo comentarios como "x = x + 7; // agregue 7 a x". Como, wow, gracias, si hubiera olvidado lo que significa un signo más, eso podría haber sido muy útil. En lo que realmente podría estar confundido es en saber qué es "x" o por qué fue necesario agregarle 7 en este momento en particular. Este código puede hacerse autodocumentado dando un nombre más significativo a "x" y usando una constante simbólica en lugar de 7. Al igual que si hubiera escrito "total_price = total_price + MEMBERSHIP_FEE;", entonces probablemente no sea necesario un comentario .

Suena genial decir que el nombre de una función debería decirle exactamente lo que hace una función para que cualquier comentario adicional sea redundante. Tengo buenos recuerdos de la época en que escribí una función que verificaba si un número de elemento estaba en nuestra tabla de elementos de la base de datos, devolviendo verdadero o falso, y al que llamé, "ValidateItemNumber". Parecía un nombre decente. Luego apareció otra persona y modificó esa función para crear también un pedido para el artículo y actualizar la base de datos, pero nunca cambió el nombre. Ahora el nombre era muy engañoso. Parecía que hizo una pequeña cosa, cuando realmente hizo mucho más. Más tarde, alguien incluso sacó la parte sobre la validación del número de artículo y lo hizo en otro lugar, pero aún así no cambió el nombre. Entonces, aunque la función ahora no tiene nada que ver con la validación de números de artículo,

Pero en la práctica, a menudo es imposible que el nombre de una función describa completamente lo que hace la función sin que el nombre de la función sea tan largo como el código que constituye esa función. ¿El nombre nos dirá exactamente qué validaciones se realizan en todos los parámetros? ¿Qué sucede en condiciones de excepción? ¿Deletrear cada posible ambigüedad? En algún momento, el nombre se alargaría tanto que se volvería confuso. Acepto String BuildFullName (String firstname, String lastname) como una firma de función decente. Aunque eso no explica si el nombre se expresa "primero último" o "último, primero" o alguna otra variación, qué hace si una o ambas partes del nombre están en blanco, si impone límites en la longitud combinada y qué hace si se excede,

Arrendajo
fuente