¿Qué hay de malo con los comentarios que explican el código complejo?

231

Mucha gente afirma que "los comentarios deben explicar 'por qué', pero no 'cómo'". Otros dicen que "el código debe ser auto-documentado" y los comentarios deben ser escasos. Robert C. Martin afirma que (reformulado a mis propias palabras) a menudo "los comentarios son disculpas por el código mal escrito".

Mi pregunta es la siguiente:

¿Qué tiene de malo explicar un algoritmo complejo o una pieza de código larga y complicada con un comentario descriptivo?

De esta manera, en lugar de que otros desarrolladores (incluyéndote a ti mismo) tengan que leer el algoritmo entero línea por línea para descubrir qué hace, solo pueden leer el comentario descriptivo y amigable que escribiste en inglés simple.

El inglés está 'diseñado' para que los humanos lo entiendan fácilmente. Java, Ruby o Perl, sin embargo, han sido diseñados para equilibrar la legibilidad humana y la legibilidad por computadora, comprometiendo así la legibilidad humana del texto. Un humano puede entender una pieza de inglés mucho más rápido que él / ella puede entender una pieza de código con el mismo significado (siempre que la operación no sea trivial).

Entonces, después de escribir una pieza compleja de código escrita en un lenguaje de programación legible para el ser humano, ¿por qué no agregar un comentario descriptivo y conciso que explique el funcionamiento del código en un inglés amigable y comprensible?

Algunos dirán "el código no debería ser difícil de entender", "hacer que las funciones sean pequeñas", "usar nombres descriptivos", "no escribir código de espagueti".

Pero todos sabemos que eso no es suficiente. Estas son meras pautas, importantes y útiles, pero no cambian el hecho de que algunos algoritmos son complejos. Y, por lo tanto, son difíciles de entender cuando se leen línea por línea.

¿Es realmente tan malo explicar un algoritmo complejo con algunas líneas de comentarios sobre su funcionamiento general? ¿Qué tiene de malo explicar un código complicado con un comentario?

    
pregunta Aviv Cohn 01.09.2014 - 02:28

16 respuestas

402

En términos sencillos:

  • No hay nada de malo en los comentarios per se.
  • Lo que está mal es escribir un código que necesita ese tipo de comentarios.
  • Lo que está mal es suponer que está bien escribir código enrevesado siempre que lo expliques de forma sencilla y sencilla.
  • Los comentarios no se actualizan automáticamente cuando cambias el código. Es por eso que muchas veces los comentarios no están sincronizados con el código.
  • Los comentarios no hacen que el código sea más fácil de probar.
  • Disculparse no es malo. Lo que hiciste que requiere disculparse es malo.
  • Un programador que es capaz de escribir código simple para resolver un problema complejo es mejor que uno que escribe código complejo y luego escribe un largo comentario que explica lo que hace su código.

Línea inferior:

Explicarte a ti mismo es bueno, no tener que hacerlo es mejor.

    
respondido por el Tulains Córdova 01.09.2014 - 02:52
109

Hay muchas razones diferentes para que el código sea complicado o confuso. Las razones más comunes se abordan mejor refactorizando el código para hacerlo menos confuso, no agregando comentarios de ningún tipo.

Sin embargo, hay casos en los que un comentario bien elegido es la mejor opción.

  • Si es el algoritmo en sí mismo lo que es complicado y confuso, no solo su implementación, del tipo que se escribe en las revistas de matemáticas y se denomina Algoritmo de Mbogo, entonces Pusiste un comentario al comienzo de la implementación, leyendo algo como "Este es el algoritmo de Mbogo para volver a generar widgets, originalmente descrito aquí: [URL del documento]. Esta implementación contiene refinamientos de Alice y Carol [URL de otro documento]". No trates de entrar en más detalles que eso; Si alguien necesita más detalles, probablemente necesite leer todo el documento.

  • Si ha tomado algo que puede escribirse como una o dos líneas en alguna notación especializada y lo ha expandido en un gran globo de código imperativo, poner esas una o dos líneas de notación especializada en un comentario sobre la función es una una buena manera de decirle al lector qué se supone que debe hacer. Esta es una excepción al argumento "pero si el comentario no está sincronizado con el código", porque la notación especializada es probablemente mucho más fácil de encontrar errores que el código. (Es al revés si en cambio escribiste una especificación en inglés). Un buen ejemplo es aquí: enlace ...

    /**
     * Scan a unicode-range token.  These match the regular expression
     *
     *     u\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?
     *
     * However, some such tokens are "invalid".  There are three valid forms:
     *
     *     u+[0-9a-f]{x}              1 <= x <= 6
     *     u+[0-9a-f]{x}\?{y}         1 <= x+y <= 6
     *     u+[0-9a-f]{x}-[0-9a-f]{y}  1 <= x <= 6, 1 <= y <= 6
    
  • Si el código es sencillo en general, pero contiene una o dos cosas que parecen excesivamente complicadas, innecesarias o simplemente erróneas, pero tienen que ser así debido a razones, entonces debes poner un comentario. inmediatamente por encima del bit de aspecto sospechoso, en el que indica los motivos . Aquí hay un ejemplo simple, donde lo único que necesita ser explicado es por qué una constante tiene un cierto valor.

    /* s1*s2 <= SIZE_MAX if s1 < K and s2 < K, where K = sqrt(SIZE_MAX+1) */
    const size_t MUL_NO_OVERFLOW = ((size_t)1) << (sizeof(size_t) * 4);
    if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
        nmemb > 0 && SIZE_MAX / nmemb < size)
      abort();
    
respondido por el zwol 01.09.2014 - 04:35
61
  

Entonces, ¿qué tiene de malo explicar un código complicado con un comentario?

No es una cuestión de correcto o incorrecto, sino de la "mejor práctica", como se define en el artículo de Wikipedia :

  

Una mejor práctica es un método o técnica que se ha demostrado constantemente   Resultados superiores a los obtenidos con otros medios, y que se utilizan.   como punto de referencia.

Entonces, la mejor práctica es tratar de mejorar el código primero y usar el inglés si eso no es posible.

No es una ley, pero es mucho más común encontrar código comentado que requiera refactorización que código refactorizado que requiera comentarios, la mejor práctica refleja esto.

    
respondido por el FMJaguar 01.09.2014 - 03:25
52

Llegará un día en que su hermoso código, perfectamente diseñado, bien estructurado y legible no funcionará. O no funcionará lo suficientemente bien. O surgirá un caso especial donde no funciona y necesita ajustes.

En ese momento, deberá hacer algo que cambie las cosas para que funcione correctamente. Particularmente en el caso de que haya problemas de rendimiento, pero también a menudo en escenarios donde una de las bibliotecas, API, servicios web, gemas o sistemas operativos con los que está trabajando no se comporta como se espera, puede terminan haciendo sugerencias que no son necesariamente poco elegantes, pero son contraintuitivas o no obvias.

Si no tiene algunos comentarios para explicar por qué ha elegido ese enfoque, existe una gran posibilidad de que alguien en el futuro (y que alguien sea usted) vea el código, vea cómo podría ser " arreglado "a algo más legible y elegante y deshacer inadvertidamente tu corrección, porque no parece una corrección.

Si todos escribieran siempre el código perfecto, sería obvio que el código que parece imperfecto está trabajando alrededor de una intervención complicada del mundo real, pero no es así como funcionan las cosas. La mayoría de los programadores a menudo escriben códigos confusos o algo enredados, de modo que cuando nos encontramos con esto, es una inclinación natural a ordenarlo. Juro que mi pasado es un verdadero idiota cada vez que leo un código antiguo que he escrito.

Así que no pienso en los comentarios como una disculpa por un código incorrecto, sino tal vez como una explicación de por qué no hiciste lo obvio. Tener // The standard approach doesn't work against the 64 bit version of the Frobosticate Library permitirá a los futuros desarrolladores, incluido su futuro yo, prestar atención a esa parte del código y realizar pruebas contra esa biblioteca. Claro, también puede poner los comentarios en los controles de código fuente, pero la gente solo los verá después de que algo salga mal. Leerán los comentarios del código a medida que cambien el código.

Las personas que nos dicen que siempre deberíamos estar escribiendo código teóricamente perfecto no siempre son personas con mucha experiencia en programación en entornos del mundo real. A veces necesita escribir código que se desempeña a un cierto nivel, a veces necesita interoperar con sistemas imperfectos. Eso no significa que no pueda hacerlo de manera elegante y bien escrita, pero las soluciones no obvias necesitan una explicación.

Cuando estoy escribiendo un código para proyectos de pasatiempos que sé que nadie más leerá, sigo comentando partes que me parecen confusas, por ejemplo, cualquier geometría 3D involucra matemáticas con las que no estoy del todo bien, porque sé cuándo Regresaré en seis meses, habré olvidado por completo cómo hacer esto. Eso no es una disculpa por un código incorrecto, es un reconocimiento de una limitación personal. Todo lo que haría al dejarlo sin comentarios es crear más trabajo para mí en el futuro. No quiero que mi futuro yo tenga que volver a aprender algo innecesariamente si puedo evitarlo ahora. ¿Qué posible valor tendría?

    
respondido por el glenatron 01.09.2014 - 12:47
29

La necesidad de comentarios es inversamente proporcional al nivel de abstracción del código.

Por ejemplo, el lenguaje ensamblador es, para los fines más prácticos, ininteligible sin comentarios. Aquí hay un extracto de un pequeño programa que calcula e imprime los términos de la serie de Fibonacci :

main:   
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ; 
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ; 
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;

Incluso con comentarios, puede ser bastante complicado de asimilar.

Ejemplo moderno: las expresiones regulares son a menudo construcciones de abstracción muy bajas (letras minúsculas, números 0, 1, 2, nuevas líneas, etc.). Probablemente necesiten comentarios en forma de muestras (Bob Martin, IIRC, sí lo reconoce). Aquí hay una expresión regular que (creo) debería coincidir con las URL de HTTP (S) y FTP:

^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\+&amp;%\$#\=~_\-]+))*$

A medida que los idiomas avanzan hacia la jerarquía de abstracción, el programador puede utilizar abstracciones evocadoras (nombre de variable, nombres de funciones, nombres de clase, nombres de módulos, interfaces, devoluciones de llamada, etc.) para proporcionar documentación integrada. Negarse a tomar ventaja de esto, y usar comentarios para escribir sobre él es perezoso, una falta de respeto y una falta de respeto al mantenedor.

Estoy pensando en que Recetas Numéricas en C se tradujeron mayormente en forma literal a Recetas Numéricas en C ++ , que inferí que comenzó como Recetas Numéricas (en FORTAN), con todas las variables a , aa , b , c , cc , etc. mantenidas a través de cada versión. Los algoritmos pueden haber sido correctos, pero no aprovecharon las abstracciones proporcionadas por los idiomas. Y me jodieron. Ejemplo de un artículo del Dr. Dobbs - Transformada rápida de Fourier :

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}

Como un caso especial sobre la abstracción, cada idioma tiene modismos de código de idioma / canónicos para ciertas tareas comunes (eliminar una lista enlazada dinámica en C), y sin importar cómo se vean, no deben documentarse. Los programadores deben aprender estos modismos, ya que no son oficialmente parte del lenguaje.

Por lo tanto, la eliminación: el código no idiomático creado a partir de bloques de construcción de bajo nivel que no pueden evitarse necesita comentarios. Y esto es necesario WAAAAY menos de lo que sucede.

    
respondido por el Kristian H 02.09.2014 - 17:42
19

No creo que haya nada malo con los comentarios en el código. La idea de que los comentarios son de alguna manera malos en mi opinión se debe a que algunos programadores están llevando las cosas demasiado lejos. Hay mucho movimiento en esta industria, particularmente hacia vistas extremas. En algún punto del camino, el código comentado se volvió equivalente a un código incorrecto y no estoy seguro de por qué.

Los comentarios tienen problemas: debe mantenerlos actualizados a medida que actualiza el código al que hacen referencia, lo que sucede con muy poca frecuencia. Un wiki o algo es un recurso más apropiado para una documentación completa sobre su código. Su código debe ser legible sin requerir comentarios. El control de versión o las notas de revisión deben estar donde describe los cambios de código que realizó.

Sin embargo, ninguno de los anteriores invalida el uso de comentarios. No vivimos en un mundo ideal, por lo que cuando cualquiera de los anteriores falla por cualquier motivo, prefiero tener algunos comentarios para retroceder.

    
respondido por el Roy 01.09.2014 - 16:10
18

Creo que estás leyendo demasiado a lo que él está diciendo. Hay dos partes distintas en su queja:

  

¿Qué tiene de malo explicar (1) un algoritmo complejo o (2) un fragmento de código largo y complicado con un comentario descriptivo?

(1) es inevitable. No creo que Martin estuviera en desacuerdo contigo. Si estás escribiendo algo como raíz cuadrada inversa rápida , necesitarás algunos comentarios, aunque solo sea "mal nivel de punto flotante bit hacking". Salvo algo simple como una búsqueda DFS o binaria, es poco probable que la persona que lea su código tenga experiencia con ese algoritmo, por lo que creo que debería haber al menos una mención en los comentarios sobre lo que es.

La mayoría del código no es (1), sin embargo. Rara vez escribirá una pieza de software que no sea más que implementaciones de mutex enrolladas a mano, operaciones de álgebra lineal oscura con poco soporte de biblioteca y algoritmos novedosos que solo el grupo de investigación de su empresa conoce. La mayoría del código consiste en llamadas de biblioteca / marco / API, IO, repetitivo y pruebas unitarias.

Este es el tipo de código del que habla Martin. Y él responde a su pregunta con la cita de Kernighan y Plaugher en la parte superior del capítulo:

  

No comentar código incorrecto, escríbelo de nuevo.

Si tienes secciones largas y complicadas en tu código, no has podido mantener limpio tu código . La mejor solución a este problema no es escribir un comentario de un párrafo de largo en la parte superior del archivo para ayudar a los futuros desarrolladores a salir adelante; La mejor solución es reescribirlo.

Y esto es exactamente lo que Martin dice:

  

El uso correcto de los comentarios es compensar nuestra falta de expresión en el código ... Los comentarios siempre son fallos. Debemos tenerlos porque no siempre podemos descubrir cómo expresarnos sin ellos. , pero su uso no es motivo de celebración.

Este es tu (2). Martin está de acuerdo en que el código largo y enrevesado necesita comentarios, pero culpa al código por parte del programador que lo escribió, no por una idea nebulosa de que "todos sabemos que eso no es suficiente". Argumenta que:

  

El código claro y expresivo con pocos comentarios es muy superior al código abarrotado y complejo con muchos comentarios. En lugar de dedicar su tiempo a escribir los comentarios que explican el desastre que ha hecho, inviértalo a limpiar ese desastre.

    
respondido por el Patrick Collins 01.09.2014 - 04:53
8
  

¿Qué tiene de malo explicar un algoritmo complejo o una pieza de código larga y complicada con un comentario descriptivo?

Nada como tal. Documentar tu trabajo es una buena práctica.

Dicho esto, tienes una falsa dicotomía aquí: escribir código limpio en lugar de escribir código documentado; los dos no están en oposición.

En lo que debería centrarse es en simplificar y abstraer código complejo en código más simple, en lugar de pensar que "el código complejo está bien siempre y cuando esté comentado".

Idealmente, su código debería ser simple y documentado.

  

De esta manera, en lugar de que otros desarrolladores (incluyéndote a ti mismo) tengan que leer el algoritmo entero línea por línea para descubrir qué hace, solo pueden leer el comentario descriptivo y amigable que escribiste en inglés simple.

Verdadero. Esta es la razón por la que todos los algoritmos de API públicos deben explicarse en la documentación.

  

Entonces, después de escribir una pieza compleja de código escrita en un lenguaje de programación legible para el ser humano, ¿por qué no agregar un comentario descriptivo y conciso que explique el funcionamiento del código en un inglés amigable y comprensible?

Lo ideal sería que, después de escribir un fragmento de código complejo, no (una lista exhaustiva):

  • considérelo un borrador (es decir, planee reescribirlo)
  • formalice los puntos de entrada de algoritmo / interfaces / roles / etc (analice y optimice la interfaz, formalice las abstracciones, las condiciones previas de los documentos, las condiciones posteriores y los efectos secundarios y los casos de errores de documentos).
  • pruebas de escritura
  • limpieza y refactorización

Ninguno de estos pasos es trivial de hacer (es decir, cada uno puede tomar algunas horas) y las recompensas por hacerlo no son inmediatas. Como tales, estos pasos (casi) siempre están comprometidos (por parte de los desarrolladores, los gerentes, los plazos, las limitaciones del mercado / otras condiciones del mundo real, la falta de experiencia, etc.).

  

[...] algunos algoritmos son complejos. Y, por lo tanto, son difíciles de entender al leerlos línea por línea.

Nunca debes tener que confiar en leer la implementación para descubrir qué hace una API. Cuando hace eso, está implementando un código de cliente basado en la implementación (en lugar de la interfaz) y eso significa que su acoplamiento de módulos ya está ya disparado al infierno, potencialmente está introduciendo dependencias indocumentadas con cada nueva línea de Código que usted escribe, y ya está agregando deuda técnica.

  

¿Es realmente tan malo explicar un algoritmo complejo con algunas líneas de comentarios sobre su funcionamiento general?

No, eso es bueno. Sin embargo, agregar algunas líneas de comentarios no es suficiente.

  

¿Qué tiene de malo explicar un código complicado con un comentario?

El hecho de que no deberías tener un código complicado, si se puede evitar.

Para evitar códigos complicados, formalice sus interfaces, gaste ~ 8 veces más en el diseño de la API de lo que gasta en la implementación (Stepanov sugirió gastar al menos 10 veces en la interfaz, en comparación con la implementación), y vaya a desarrollar un proyecto con el conocimiento de que está creando un proyecto, no solo escribiendo algún algoritmo.

Un proyecto involucra documentación API, documentación funcional, medidas de calidad / código, gestión de proyectos, etc. Ninguno de estos procesos es una sola vez, pasos rápidos que deben realizarse (todos requieren tiempo, requieren previsión y planificación, y todos requieren que los visite periódicamente y los revise / complete con detalles).

    
respondido por el utnapistim 01.09.2014 - 14:33
6
  

en lugar de que otros desarrolladores (incluyéndote a ti mismo) tengan que leer el   algoritmo completo línea por línea para descubrir lo que hace, pueden   simplemente lea el comentario descriptivo amigable que escribió en un lenguaje sencillo.

Consideraría esto como un ligero abuso de "comentarios". Si el programador quiere leer algo en lugar de todo el algoritmo, para eso está la documentación de la función. De acuerdo, la documentación de la función podría aparecer en los comentarios en la fuente (quizás para la extracción por parte de las herramientas de documentación), pero aunque sintácticamente es un comentario en lo que respecta a su compilador, debe considerarlos por separado con propósitos diferentes. No creo que "los comentarios deben ser escasos" significa necesariamente que significa "la documentación debe ser escasa" o incluso los "avisos de derechos de autor deberían ser escasos".

Los comentarios en la función son para que alguien lea así como el código. Entonces, si tiene algunas líneas en su código que son difíciles de entender y no puede hacer que sean fáciles de entender, entonces un comentario es útil para que el lector lo use como un marcador de posición para esas líneas. Esto podría ser muy útil mientras el lector solo está tratando de obtener la esencia general, pero hay un par de problemas:

  • Los comentarios no son necesariamente verdaderos, mientras que el código hace lo que hace. Así que el lector está tomando su palabra, y esto no es lo ideal.
  • El lector aún no entiende el código en sí mismo, por lo que, hasta que vuelvan a utilizarlo más tarde, aún no están calificados para modificarlo o reutilizarlo. ¿En qué caso lo están haciendo leyendo?

Hay excepciones, pero la mayoría de los lectores deberán entender el código en sí. Los comentarios deben escribirse para ayudar a eso, no para reemplazarlo, por lo que generalmente se recomienda que los comentarios digan "por qué lo estás haciendo". Un lector que conoce la motivación para las siguientes líneas de código tiene más posibilidades de ver lo que hacen y cómo.

    
respondido por el Steve Jessop 01.09.2014 - 10:41
5

Muchas veces tenemos que hacer cosas complicadas. Ciertamente es correcto documentarlos para su futura comprensión. A veces, el lugar correcto para esta documentación se encuentra en el código, donde la documentación se puede mantener actualizada con el código. Pero definitivamente vale la pena considerar la documentación por separado. Esto también puede ser más fácil de presentar a otras personas, incluir diagramas, imágenes en color, etc. Entonces el comentario es justo:

// This code implements the algorithm described in requirements document 239.

o incluso simplemente

void doPRD239Algorithm() { ...

Ciertamente, la gente está contenta con las funciones llamadas MatchStringKnuthMorrisPratt o encryptAES o partitionBSP . Vale la pena explicar los nombres más oscuros en un comentario. También puede agregar datos bibliográficos y un enlace a un documento en el que haya implementado un algoritmo.

Si un algoritmo es complejo y novedoso y no es obvio, definitivamente vale la pena un documento, aunque solo sea para la circulación interna de la empresa. Verifique el documento en el control de código fuente si está preocupado de que se pierda.

Hay otra categoría de código que no es tan algorítmica como burocrática. Debe configurar los parámetros para otro sistema o interoperar con los errores de otra persona:

/* Configure the beam controller and turn on the laser.
The sequence is timing-critical and this code must run with interrupts disabled.
Note that the constant 0xef45ab87 differs from the vendor documentation; the vendor
is wrong in this case.
Some of these operations write the same value multiple times. Do not attempt
to optimise this code by removing seemingly redundant operations.
*/
    
respondido por el pjc50 01.09.2014 - 16:50
5

Olvidé dónde lo leí, pero hay una línea clara y nítida entre lo que debería aparecer en tu código y lo que debería aparecer como comentario.

Creo que deberías comentar tu intención, no tu algoritmo . Es decir. comente lo que quería hacer, no sobre lo que hace .

Por ejemplo:

// The getter.
public <V> V get(final K key, Class<V> type) {
  // Has it run yet?
  Future<Object> f = multitons.get(key);
  if (f == null) {
    // No! Make the task that runs it.
    FutureTask<Object> ft = new FutureTask<Object>(
            new Callable() {

              public Object call() throws Exception {
                // Only do the create when called to do so.
                return key.create();
              }

            });
    // Only put if not there.
    f = multitons.putIfAbsent(key, ft);
    if (f == null) {
      // We replaced null so we successfully put. We were first!
      f = ft;
      // Initiate the task.
      ft.run();
    }
  }
  try {
    /**
     * If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
     * then you are trying to get from your Multiton in your creator.
     *
     * Cannot check for that without unnecessarily complex code.
     *
     * Perhaps could use get with timeout.
     */
    // Cast here to force the right type.
    return (V) f.get();
  } catch (Exception ex) {
    // Hide exceptions without discarding them.
    throw Throwables.asRuntimeException(ex);
  }
}

Aquí no hay ningún intento de indicar qué realiza cada paso, todo lo que establece es lo que se supone que debe hacer .

PD: encontré la fuente a la que me refería - Codificación del horror: El código te dice cómo, los comentarios te dicen por qué

    
respondido por el OldCurmudgeon 01.09.2014 - 13:06
4
  

Pero todos sabemos que eso no es suficiente.

¿De verdad? ¿Desde cuándo?

Un código bien diseñado con buenos nombres es más que suficiente en la gran mayoría de los casos. Los argumentos en contra del uso de comentarios son bien conocidos y están documentados (como se refiere a).

Pero estas son pautas (como cualquier otra cosa). En el raro caso (según mi experiencia, aproximadamente una vez cada 2 años) en el que las cosas empeorarían cuando se refactorizaran en funciones más legibles más pequeñas (debido a las necesidades de rendimiento o de cohesión), siga adelante. Haga un comentario extenso que explique lo que realmente es. haciendo (y por qué estás violando las mejores prácticas).

    
respondido por el Telastyn 01.09.2014 - 02:57
2

El propósito principal del código es ordenar a una computadora que haga algo, por lo que un buen comentario nunca es un sustituto de un buen código porque los comentarios no pueden ejecutarse.

Dicho esto, los comentarios en la fuente son una forma de documentación para otros programadores (incluido usted mismo). Si los comentarios son sobre temas más abstractos que lo que el código está haciendo en cada paso, lo está haciendo mejor que el promedio. Ese nivel de abstracción varía con la herramienta que estás usando. Los comentarios que acompañan las rutinas del lenguaje ensamblador generalmente tienen un nivel de "abstracción" más bajo que, por ejemplo, este APL A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕ . Creo que probablemente merecería un comentario sobre el problema que se pretende resolver, ¿hmm?

    
respondido por el Scott Leadley 01.09.2014 - 04:12
2

Si el código es trivial, no necesita un comentario explicativo. Si el código no es trivial, lo más probable es que el comentario explicativo no sea trivial.

Ahora, el problema con el lenguaje natural no trivial es que muchos de nosotros no somos muy buenos para leerlo o escribirlo. Estoy seguro de que sus habilidades de comunicación escritas son excelentes, pero sin embargo, alguien con un menor dominio del lenguaje escrito puede malinterpretar sus palabras.

Si te esfuerzas mucho por escribir un lenguaje natural que no pueda ser malinterpretado, terminas con algo así como un documento legal (y como todos sabemos, son más detallados y difíciles de entender que el código).

El código debería ser la descripción más concisa de su lógica, y no debería haber mucho debate sobre el significado de su código porque su compilador y plataforma tienen la última palabra.

Personalmente, no diría que nunca deberías escribir un comentario. Solo que debe considerar por qué su código necesita un comentario y cómo podría solucionarlo. Este parece ser un tema común en las respuestas aquí.

    
respondido por el Martin 01.09.2014 - 15:00
0

Un punto que aún no se ha mencionado es que a veces comentar con precisión lo que hace un trozo de código puede ser útil en los casos en que un idioma usa una sintaxis particular para múltiples propósitos. Por ejemplo, suponiendo que todas las variables son de tipo float , considere:

f1 = (float)(f2+f3); // Force result to be rounded to single precision
f4 = f1-f2;

El efecto de convertir explícitamente un float a float es forzar el resultado a redondear a precisión simple; Por lo tanto, el comentario podría verse como simplemente diciendo lo que hace el código. Por otro lado, compara ese código con:

thing.someFloatProperty = (float)(f2*0.1); // Divide by ten

Aquí, el propósito del reparto es evitar que el compilador emita un chirrido de la manera más eficiente de computar con precisión (f2 / 10) [es más preciso que multiplicar por 0.1f, y en la mayoría de las máquinas es más rápido que dividir por 10.0 f].

Sin el comentario, alguien que estaba revisando el código anterior podría pensar que el reparto se agregó con la creencia errónea de que sería necesario para evitar que el compilador grabe y que no era necesario. De hecho, el reparto tiene el propósito de hacer exactamente lo que la especificación de lenguaje dice que hace: obliga a redondear el resultado del cálculo a precisión simple incluso en máquinas donde el redondeo sería más costoso que mantener el resultado con mayor precisión. Dado que una conversión a float puede tener varios significados y propósitos diferentes, tener un comentario que especifique qué significado se pretende en un escenario particular puede ayudar a aclarar que el significado real se alinea con la intención.

    
respondido por el supercat 01.09.2014 - 17:35
-1

Los comentarios que explican lo que hace el código son una forma de duplicación. Si cambia el código y luego olvida actualizar los comentarios, esto puede causar confusión. No estoy diciendo que no los use, solo utilícelos con criterio. Me suscribo a la máxima del tío Bob: "Solo comente lo que el código no puede decir".

    
respondido por el murungu 07.02.2015 - 13:36

Lea otras preguntas en las etiquetas