Supongamos que estoy desarrollando un proyecto relativamente grande. Ya he documentado todas mis clases y funciones con Doxygen, sin embargo, tuve la idea de poner "notas de programador" en cada archivo de código fuente.
La idea detrás de esto es explicar en términos simples cómo funciona una clase específica (y no solo por qué, como lo hacen la mayoría de los comentarios). En otras palabras, darles a otros programadores una visión diferente de cómo funciona una clase.
Por ejemplo:
/*
* PROGRAMMER'S NOTES:
*
* As stated in the documentation, the GamepadManager class
* reads joystick joystick input using SDL and 'parses' SDL events to
* Qt signals.
*
* Most of the code here is about goofing around the joystick mappings.
* We want to avoid having different joystick behaviours between
* operating systems to have a more integrated user experience, since
* we don't want team members to have a bad surprise while
* driving their robots with different laptops.
*
* Unfortunately, we cannot use SDL's GamepadAPI because the robots
* are interested in getting the button/axes numbers, not the "A" or
* "X" button.
*
* To get around this issue, we created a INI file for the most common
* controllers that maps each joystick button/axis to the "standard"
* buttons and axes used by most teams.
*
* We choose to use INI files because we can safely use QSettings
* to read its values and we don't have to worry about having to use
* third-party tools to read other formats.
*/
¿Sería esta una buena manera de hacer que un proyecto grande sea más fácil para que los nuevos programadores / contribuyentes entiendan cómo funciona? Además de mantener un estilo de codificación coherente y una organización de directorio 'estándar', ¿existen 'estándares' o recomendaciones para estos casos?
fuente
Respuestas:
Esto es asombroso Deseo que más desarrolladores de software se tomen el tiempo y el esfuerzo para hacer esto. Eso:
Por desgracia, muchos programadores caen en el campo de "si el código está escrito correctamente, no debería tener que documentarse". No es verdad. Hay muchas relaciones implícitas entre clases de código, métodos, módulos y otros artefactos que no son obvios simplemente leyendo el código en sí.
Un codificador experimentado puede diseñar cuidadosamente un diseño que tenga una arquitectura clara y fácil de entender que sea obvia sin documentación. Pero, ¿cuántos programas como ese has visto realmente?
fuente
how a class works
. Esto cambia con el tiempo y el mantenimiento. Aunque mi equipo no pone lo anterior en la fuente. Mantenemos un wiki con decisiones y copiamos la discusión del canal flojo sobre decisiones de diseño sin procesar en un documento (Proporcionamos un enlace desde el resumen y la conclusión de la decisión hasta las notas sin procesar para que no tengamos que volver a analizar las decisiones antiguas). Todo bien hecho en github (por lo que está todo en un solo lugar).La clave para trabajar con una base de código grande es no tener que leer la base de código completa para hacer un cambio. Para permitir que un programador encuentre rápidamente el código que está buscando, el código debe estar organizado y la organización debe ser aparente. Es decir, cada unidad lógica en el código, desde el ejecutable, la biblioteca, el espacio de nombres, hasta la clase individual debe tener una responsabilidad claramente aparente. Por lo tanto, no solo documentaría los archivos fuente, sino también los directorios en los que residen.
Las notas de su programador también brindan antecedentes sobre las decisiones de diseño. Si bien esta puede ser información valiosa, la separaría de la declaración de responsabilidad (para que el lector pueda elegir si quiere leer sobre la responsabilidad de la clase o su lógica de diseño) y acercarla a la fuente que describe como sea posible, para maximizar la posibilidad de que la documentación se actualice cuando el código es (la documentación solo es útil si podemos confiar en su precisión; ¡la documentación obsoleta puede ser peor que ninguna!).
Dicho esto, la documentación debe permanecer SECA, es decir, no repetir información que podría haberse expresado en código o que ya se describió en otra parte (frases como "como dice la documentación" son una señal de advertencia). En particular, los futuros mantenedores solo serán competentes en el lenguaje de programación del proyecto, ya que están en inglés; parafrasear la implementación en los comentarios (que veo con demasiada frecuencia cuando la gente está orgullosa de su documentación) no tiene ningún beneficio, y es probable que difiera de la implementación, en particular si la documentación no está cerca del código que describe.
Finalmente, la estructura de la documentación debe estandarizarse en todo el proyecto para que todos puedan encontrarla (es un desastre real de documentos de Peter en el rastreador de errores, Sue en la wiki, Alan en el archivo Léame y John en el código fuente ...) .
fuente
No estaría de acuerdo con que este es un enfoque muy bueno, principalmente debido a
Cuando refactoriza su proyecto, mueve los métodos, la documentación se rompe.
Si la documentación no se actualiza correctamente, generará más confusión que ayuda para comprender el código.
Si tiene pruebas unitarias para cada método / pruebas de integración para cada módulo, sería una auto documentación más fácil de mantener y más fácil de entender en comparación con los comentarios de código.
Sí, tener una estructura de directorios adecuada definitivamente va a ayudar.
fuente
Personalmente, soy fanático de un documento de diseño de alto nivel, preferiblemente escrito ANTES de cualquier código, que brinde una descripción general del diseño y una lista de clases y recursos. Un diseño de arriba hacia abajo simplifica enormemente las cosas: el suyo podría ser "motor de juego -> hardware -> controladores -> joystick"; por lo tanto, un nuevo programador le dijo a "arreglar el botón 'a' en el controlador 'xyz" al menos sabría dónde comenzar a buscar.
Demasiados lenguajes modernos tienden a dividir el código en cientos de archivos pequeños, por lo que solo encontrar el archivo correcto puede ser un desafío incluso en un proyecto moderado.
fuente
Si la base del código es grande, trato de proporcionar un documento de diseño que mapee los elementos clave de su diseño y la implementación . La intención aquí no es detallar ninguna de las clases utilizadas, sino proporcionar una clave para el código y el pensamiento que se incluyó en el diseño. Da un contexto general al sistema, sus componentes y la aplicación del mismo.
Las cosas para incluir en el documento de diseño son;
A continuación, se debe completar la documentación de las clases y las funciones / métodos, según corresponda . En particular la API pública; debe quedar claro cuáles son los siguientes en cada caso;
fuente
La regla más importante que he encontrado para facilitar que los nuevos desarrolladores entiendan que una base de código es que el acuerdo perfecto es costoso.
Si los nuevos desarrolladores deben comprender perfectamente el sistema en el que están trabajando, evita todas las oportunidades de aprendizaje en el trabajo. Creo que las notas del programador son un excelente comienzo, pero iría más lejos. Intente escribir un código que, si se aborda de nuevo, permitiría a un desarrollador averiguar qué están haciendo sobre la marcha, en lugar de exigirles que aprendan antes de hacerlo. Pequeñas cosas como afirmaciones para casos que usted sabe que nunca pueden ocurrir, junto con comentarios que explican por qué la afirmación es válida, hacen mucho. También lo hace escribir código que falla con gracia en lugar de segfaular si haces algo mal.
fuente
¡He visto clases grandes con documentación, y después de leer la documentación no tengo ni idea de para qué se supone que esta clase es buena y por qué alguien la usaría! Y al mismo tiempo, necesitaba algo de funcionalidad y estaba absolutamente seguro de que debía haber una clase para manejarlo, y no podía encontrarlo en ninguna parte, porque no había documentación que me llevara de lo que necesitaba a la clase. haciéndolo.
Entonces, lo primero que querría en la documentación son solo unas pocas oraciones sobre lo que hace una clase y por qué me gustaría usarla. Los comentarios en la pregunta original lo están haciendo bastante bien en ese sentido. Después de leer estos comentarios, si tuviera un joystick que no funciona bien porque no puedo interpretar los valores que ofrece, sabría qué código verificar.
fuente
Similar a lo que dijo @meriton, divida el código en componentes separados. Aún mejor, descomponga la base de código en paquetes separados (JAR, gemas, huevos, lo que sea) para que quede aún más claro cómo se separan los componentes. Si hay un error, un desarrollador solo necesita encontrar el paquete donde está el error y (con suerte) solo solucionarlo allí. Sin mencionar que es más fácil hacer pruebas unitarias y aprovechar la administración de dependencias.
Otra solución: hacer la base de código más pequeña. Cuanto menos código haya, más fácil será de entender. Refactorice el código no utilizado o duplicado. Utiliza técnicas de programación declarativa . Esto requiere esfuerzo, por supuesto, y a menudo no es posible o práctico. Pero es un objetivo digno. Como Jeff Atwood ha escrito: El mejor código no es ningún código
fuente
Para sistemas complejos, puede valer la pena no solo documentar cada archivo, sino también sus interacciones y jerarquía, y cómo se estructura el programa y por qué.
Por ejemplo, un motor de juego suele ser bastante complejo y es difícil decidir qué se llama después de cientos de capas de abstracción. Puede valer la pena crear un archivo como "Architecture.txt" para explicar cómo y por qué está estructurado el código de esta manera, y por qué existe esa capa de abstracción de aspecto inútil allí.
fuente
Esto puede deberse en parte a que es difícil para un solo programador escribirlo, ya que cada individuo comprende solo su parte del proyecto.
A veces puede obtener esta información de las notas del administrador del proyecto, pero eso es todo lo que obtendrá, ya que rara vez reescribirán sus notas en este formato.
fuente