Cómo hacer que una base de código grande sea más fácil de entender para los nuevos programadores

102

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 del programador" en cada archivo de código fuente.

La idea detrás de esto es explicar en términos sencillos cómo funciona una clase específica (y no solo por qué como lo hace la mayoría de los comentarios). En otras palabras, para ofrecer a los 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 gran proyecto sea más fácil para los nuevos programadores / colaboradores para comprender cómo funciona? Además de mantener un estilo de codificación coherente y una organización de directorios "estándar", ¿existen "estándares" o recomendaciones para estos casos?

    
pregunta Alex Spataru 01.08.2015 - 00:33
fuente

10 respuestas

135

Esto es impresionante. Deseo que más desarrolladores de software se tomen el tiempo y el esfuerzo para hacer esto. Es:

  • Declara en inglés simple lo que hace la clase (es decir, es su responsabilidad),
  • Proporciona información complementaria útil sobre el código sin repetir lo que ya dice el código,
  • Describe algunas de las decisiones de diseño y por qué se tomaron, y
  • Resalta algunos de los errores que podrían surgir a la siguiente persona que lea tu código.

Por desgracia, muchos programadores caen en el campo de "si el código está escrito correctamente, no debería tener que estar documentado". 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 programador experimentado puede diseñar cuidadosamente un diseño que tenga una arquitectura clara y fácilmente comprensible que sea evidente sin documentación. ¿Pero cuántos programas como ese has visto realmente?

    
respondido por el Robert Harvey 01.08.2015 - 00:42
fuente
35

La clave para trabajar con una base de código grande es no tener que leer la base de código completa para realizar 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 evidente. 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 evidente. Por lo tanto, no solo documentaría los archivos de origen, sino también los directorios en los que residen.

Las notas de su programador también proporcionan información sobre las decisiones de diseño. Si bien esta información puede ser valiosa, la separaría de la declaración de responsabilidad (para permitir que el lector elija si desea leer acerca de la responsabilidad de la clase o su razón de diseño) y la mueva tan cerca de la fuente que describe como sea posible, para maximizar la posibilidad de que la documentación se actualice cuando el código lo está (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 la información que podría haberse expresado en un código o que ya se describió en otra parte (frases como "como indica 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 comentarios (que veo con demasiada frecuencia cuando las personas están orgullosas de su documentación) no tiene beneficios, y es probable que se diferencie 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 lío 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). ..).

    
respondido por el meriton 01.08.2015 - 11:26
fuente
13

No estaría de acuerdo, este es un muy buen enfoque, principalmente debido a

  1. Cuando refactoriza su proyecto, mueve los métodos, la documentación se rompe.

  2. Si la documentación no se actualiza correctamente, generará más confusión que ayuda para entender 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 comprender en comparación con los comentarios de código.

Sí, tener una estructura de directorios adecuada definitivamente te ayudará.

    
respondido por el Low Flying Pelican 02.08.2015 - 11:55
fuente
7

Personalmente, soy un fanático de un documento de diseño de alto nivel, preferiblemente escrito ANTES de cualquier código, que brinda 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 tuyo puede ser "motor del juego - > hardware - > controles - > joystick"; por lo tanto, un nuevo programador le dijo a "arreglar el botón 'a' en el 'controlador xyz' que al menos sabría dónde empezar a buscar.

Demasiados idiomas 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.

    
respondido por el DWalker 01.08.2015 - 10:58
fuente
5

Si el código base es grande, intento proporcionar un documento de diseño que muestre 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. Proporciona un contexto general al sistema, sus componentes y la aplicación del mismo.

Las cosas para incluir en el documento de diseño son:

  • arquitectura de la aplicación
  • estructura de código lógico
  • Flujos de datos
  • Patrones clave utilizados y la motivación detrás de su uso
  • Estructura de código fuente
  • Cómo construirlo (esto ofrece información sobre las dependencias implícitas y la estructura de la fuente del código físico)

Después de esto, se debe completar la documentación para 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;

  • Condiciones previas
  • Efectos
  • Invariantes
  • Condiciones de excepción (lanzamientos)
respondido por el Niall 03.08.2015 - 11:02
fuente
4

La regla más importante que he encontrado para facilitar a los nuevos desarrolladores la comprensión de un código base es que el acuerdo perfecto es caro.

Si los nuevos desarrolladores deben comprender perfectamente el sistema en el que están trabajando, se evitarán todas las oportunidades de aprendizaje en el trabajo. Creo que las notas del programador son un excelente comienzo, pero yo iría más allá. Intente escribir un código que, si se lo aborda de nuevo, permitiría a un desarrollador averiguar qué está haciendo sobre la marcha, en lugar de requerir que aprendan antes de que lo hagan. Pequeñas cosas como las afirmaciones para los casos que sabe que nunca pueden ocurrir, junto con los comentarios que explican por qué la afirmación es válida, van muy lejos. Lo mismo ocurre al escribir código que falla con gracia en lugar de segregar si haces algo mal.

    
respondido por el Cort Ammon 02.08.2015 - 08:51
fuente
3

He visto clases grandes con documentación y, después de leer la documentación, no tengo ni idea de para qué sirve esta clase 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 frases de lo que hace una clase y por qué querría usarla. Los comentarios en la pregunta original lo están haciendo bastante bien a ese respecto. Después de leer estos comentarios, si tuviera un joystick que no funciona bien porque no puedo interpretar los valores que entrega, sabría qué código verificar.

    
respondido por el gnasher729 02.08.2015 - 22:21
fuente
0

Similar a lo que dijo @meriton, divide el código en componentes separados. Aún mejor, divida la base de código en paquetes separados (JAR, gemas, huevos, lo que sea) para que sea 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 de unidad y puedes aprovechar la administración de dependencias.

Otra solución: hacer el código base más pequeño. Cuanto menos código hay, más fácil es entenderlo. Refactorice el código no utilizado o duplicado. Use técnicas de programación declarativa . Esto requiere esfuerzo, por supuesto, y muchas veces no es posible o práctico. Pero es un objetivo digno. Como ha escrito Jeff Atwood: El mejor código es sin código en absoluto

    
respondido por el Sam Jones 08.08.2015 - 16:39
fuente
-1

Para sistemas complejos puede valer la pena no solo documentar cada archivo, sino 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 lo que se denomina después de cien 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 que parece inútil.

    
respondido por el akaltar 02.08.2015 - 13:25
fuente
-7

Esto puede ser en parte porque es difícil para un solo programador escribirlo, ya que cada individuo entiende 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 volverán a escribir sus notas en este formato.

    
respondido por el Ilqar Rasulov 01.08.2015 - 07:17
fuente

Lea otras preguntas en las etiquetas