Comentado de código y documentación.

Comentando código

Realizar comentarios en el código es algo fundamental para la mantenibilidad de este cuando lo volvamos a coger más adelante.

Muchas veces, sobre todo en los proyectos esos que son "para anteayer" las prisas y la necesidad de tener la versión o el producto listo para una determinada fecha hacen que los comentarios de código sean escasos, malos o inexistentes.

Al contrario de lo que puedan decir por ahí no voy a decir, "comenta siempre aunque tengas que retrasarte"; nada más lejos de la realidad, acaba el proyecto, entregalo y consigue el dinerito del cliente y que se cumpla el contrato y si eso significa que no puedes comentar una sola linea de código, es lo que toca, la proxima vez tendrás que establecer mejor los plazos de entrega.

Comentar código a posteriori es un proceso medianamente penoso, sobre todo porque es bastante tedioso de hacer, más aburrido que programar y desde luego más aburrido que haberlo hecho en el momento cuando tenías claro lo que estabas haciendo y por qué, sin embargo, como ya he dicho es un proceso que debes hacer, a ser posible mientras creas el código.

Sistemas de documentación y Tipos de comentarios

Mientras estas haciendo la carrera te enseñan unas cuantas técnicas de documentación. Fundamentalmente diagramas UML, diagramas de flujo y otros documentos de diseño válidos y formales.

Olvidate de ellos, o mejor dicho, no los olvides pero no les hagas mucho caso. Estos diagramas son correctos y adecuados, ayudan a cumplir estandares y, si se realizaran bien, ahorrarían un montón de trabajo ... el único problema que tienen es que no se realizan bien, en la mayoría de los casos al menos.

Un diagrama de flujo de datos o un diagrama UML está pensado para ser realizado antes de realizar la implementación, antes de que se empiece a implementar el producto y su objetivo fundamental es guiar ese desarrollo, definir formalmente lo que se va a desarrollar antes de desarrollarlo. Dicho esto, en la mayoría de las empresas (medianas o grandes) el proceso suele ser justo el inverso. Primero se implementa la solución porque hay que darsela en unas fechas muy justas al cliente y después se realizan todos los procesos formales que el cliente exige para garantizar la calidad del producto (esto no es siempre tan estricto, a veces se realiza parte del proceso pero no da tiempo a realizar la otra parte, etc). Esto significa que, cogiendo las especificaciones lo más probable es que ni tu ni nadie os entereis de que va el asunto.

Documentando la arquitectura

Los documentos formales están muy bien, pero nunca subestimes el poder de una buena explicación en texto claro. Si la arquitectura del sistema es medianamente compleja haz un documento explicativo, da igual el formato aunque si se pueden incluir diagramas sobre las partes que componen el sistema y la forma de relacionarse entre ellas mucho mejor. Es conveniente explicar el por qué de las decisiones de diseño que se han tomado, porque se optó o no por una aplicación distribuida, por qué se implementó una solución multihilo o como funciona el sistema de autenticación de usuarios.

El secreto consiste básicamente en escribir las cosas que vas a querer saber cuando revisites el código dentro de seis meses y la idea es que, si después de seis meses vas a decir "vaya mierda de decisión de diseño tomé" que por lo menos sepas por qué la tomaste.

Además en este documento debería ser posible observar el sistema como un todo, es decir, poder ver el funcionamiento desde un punto de vista global, viendo como fluye, por decirlo de alguna forma, el control y los datos de una parte del programa a otra así como los metodos de comunicación que hay entre las distintas partes del programa.

En general yo suelo englobar en este documento todas las cosas que considero necesarias para entender el proyecto, esto quiere decir, de forma fundamental la arquitectura del sistema pero también otras secciones que permitan entender otros aspectos que consideré importantes como por ejemplo la forma de extender la funcionalidad del programa si alguien quiere hacerlo, posibles mejoras a largo plazo o cualquier otro tipo de información que pueda ser útil.

Documentando el código

Ojo, cuando hablo de documentación de código no hablo de comentarios de código, no hablo de un par de lineas explicando que hace un determinado segmento de código que viene justo a continuación. Estoy hablando de documentar la funcionalidad que proporciona tu código, esto es, una explicación de cada clase y cada función que hay en tu programa o librería (sobre todo si es una librería).

Lo más importante es que cada función o metodo público este documentado. Que nadie (ni tu mismo) tenga que examinar la función para saber que demonios hace, es una perdida de tiempo, sobre todo si tenemos en cuenta que tu sabías lo que hacía cuando la creaste y por tanto puedes evitar(te) trabajo a todos los que vengan detrás.

Existen numerosas soluciones para la documentación de código automático. Algunos ejemplos incluyen Sandcastle para la plataforma .NET, PasDoc para Delphi, JDoc para Java o Doxygen para C++. Todas ellas analizan el código de la aplicación así como los comentarios (que deben tener un formato especial) para crear una salida en HTML (y otros formatos) que proporcionará una forma sencilla y rápida de obtener una documentación razonablemente buena. Todos ellos generan salidas similares a la se puede ver, por ejemplo, en la documentación del MSDN de Microsoft. Por ejemplo está es la documentación del propio PasDoc generada por el mismo sobre si mismo. Un ejemplo de como va quedando el código Delphi:

{ @abstract(Clase que encapsula un area rectangular) }
type TPoligonalArea = class
  private
    FTopLeft : TPoint;
    FBottomRight : TPoint;
  public
    // Coordenada superior izquierda
    property TopLeft : TPoint read FTopLeft;
    // Coordenada inferior derecha
    property BottomRight : TPoint read FBottomRight;

    { @abstract(Constructor de la clase)
      @param(Arriba La coordenada y del punto superior izquierda)
      @param(Izquierda La coordenada x del punto superior izquierda)
      @param(Ancho El ancho del rectangulo)
      @param(Alto El alto del rectangulo) }

    constructor Create(Top, Left, Width, Height : integer);
    { @abstract(Comprueba si un punto dado está dentro del rectangulo)
      @param(Punto El punto a comprobar)
      @returns(True si el punto esta dentro del rectangulo) }

    function EstaDentroPunto(Punto : TPoint) : boolean;
end;

Quizá al principio pueda parecer algo incomodo, sobre todo con la falta de costumbre, pero los resultados merecen la pena. Por un lado un simple vistazo al código, a las definiciones de las clases nos permiten saber exactamente que hace cada metodo y que es cada propiedad, por otro lado, si cualquiera desea consultar las clases que hemos desarrollados podrá hacerlo en la documentación HTML generada. Esto significa que si hay clases que pueden reutilizarse la consulta será mucho más rápida. Además podemos incluir ejemplos de uso, formas de llamada, descripciones de cuando es apropiado utilizar la clase o metodo en cuestión ... en resumen, hacernos la vida más fácil a nosotros mismos y a los que vengan detrás nuestra.

Comentando el código

El comentado de código es un "arte" que tiene tantas variantes y opiniones como programadores. Aún así podemos encontrar un axioma fundamental: no comentes lo que no necesita ser comentado. Esto significa que comentarios como:

procedure MiFuncion;
begin
  ...
  i := i + 1;  // Incrementamos i
  ...
end;

están claramente fuera de lugar pero también lo están comentarios como

function SumaLista : integer;
begin
  result := 0;
  // Sumamos todos los elementos de la lista
  for i := 0 to List.Count - 1 do
    result := result + Integer(List[i])
end;

No es que el comentario no sea correcto, es que un programador que necesite el comentario para entender lo que hace ese fragmento de código (especialmente si además miramos el nombre de la función) no merece llamarse programador. En general yo suelo utilizar la regla de comentar para mi, comentar las cosas que creo que no voy a entender en un tiempo, si un fragmento de código me parece obvio, entonces no lo comento (pero ojo, tampoco hay que sobreestimarse a uno mismo).

En general lo importante es darse cuenta de aquellos segmentos de código que son suficientemente conflictivos o "extraños" como para que cuando vuelvas a ellos no veas a simple vista que hacen. Lo ideal es no escribir lo que haces sino por qué (y quizá como) lo haces y solo escribir lo que haces si el código, por razones de rendimiento o vaya usted a saber, no es lo suficientemente claro como para que se vea a simple vista. Un ejemplo:

procedure IncRefCount;
begin
  { Incrementar ref count en ensamblador por eficiencia.
    Lock garantiza que la intrucción se realiza de forma
    atómica, [eax] contiene la dirección base del objeto
    (la variable this). Se hace en ensamblador porque
    InterlockedIncrement no funciona con tipos Byte. }

  asm
    lock inc byteptr [eax].RefCount;
  end;
end;

De esta forma estamos explicando algo que podemos encontrar extraño más adelante y preguntarnos WTF?

Otra cosa importante al comentar código, por extraño que pueda parecer es está: comenta las ñapas. Llamalas como quieras, chapuzas, arreglos... son fragmentos de código que están mal hechos y sabes que están mal hechos pero ey, el cliente dice que quiere algo para mañana asi que no tengo tiempo de diseñar una solución elegante. Perfecto, eso pasa, es el día a día del desarrollo... pero anotalo, apuntalo, a ser posible con una etiqueta descriptiva como "ÑAPA" o "MEJORAR" ... algo que luego puedas localizar facilmente para volver a ello y realmente corregirlo. Otro ejemplo:

procedure MuestraLogo;
begin
  // ÑAPA, hacer que lea el valor de la base de datos
  txtNombre.Text := 'Mi nombre de aplicación';
end;

El resto de comentarios de código es probablemente cuestión de sentido común y algo de práctica.

Historial de cambios

Más conocido como changelog.

El changelog es un pequeño fichero de texto plano que recoge el historial de cambios de una aplicación. Obviamente no tiene sentido cuando la aplicación aún no está empezada o cuando está comenzando (por ejemplo no tiene sentido incluir una entrada del tipo "ya funciona la red") pero comienza a cobrar sentido cuando el proyecto está en fase estable y comienzan a corregirse fallos y a introducirse mejoras y es absolutamente indispensable cuando varias personas trabajan en un mismo proyecto.

El formato más general del changelog suele ser como sigue:

Version 1.3

  * 13-05-2006 nmuñoz - Corregido un error que producía un cuelgue de la aplicación
                        bajo circustancias de carga.
  * 11-05-2006 operez - Implementada la funcionalidad de soporte udp (unidades udpServer.cs
                        y udpClient.cs.
  * 06-05-2006 nmuñoz - ..............

aunque este formato puede variar, en general conviene señalar, al menos, la fecha en la que se realiza una modificación, el autor de la modificación y la modificación en si misma.

Este proceso nos va a ahorrar muchos problemas, el primero, el encontrar al responsable de un cambio para preguntarle sobre él. Cuando en un proyecto trabajan 5 o 6 personas (no digamos ya más), creeme, puedes perder mucho tiempo buscando a la persona que ha realizado un cambio para, por ejemplo, explicarle por que su cambio esta fastidianto una parte de tu código.

Además de eso, si se han entregado distintas versiones de un producto a un cliente se puede averiguar que fallos se corrigieron para cada versión así como que fallos se han corregido después de que una determinada versión fuera entregada.

Conclusiones

Documentar código es un proceso tedioso, sobre todo para los programadores puros a los que nos gusta mucho más programar que documentar. Sin embargo es un proceso que, a la larga, nos va a evitar un montón de dolores de cabeza y que, en la medida de lo posible es conveniente adoptar y hacer que forme parte de nuestra forma normal de programar, haciendo que los comentarios y la documentación sean casi una parte de la programación tan automática como crear un bucle o escribir un if then.

0
No votes yet
Your rating: None