Ingeniería del Software II

jueves, 1 de mayo de 2014

¿Cómo documentar un sistema de software?


     Un sistema pobremente documentado carece de valor aunque haya funcionado bien en alguna ocasión. En el caso de programas pequeños y poco importantes que sólo se utilizan durante un corto periodo de tiempo, unos cuantos comentarios en el código podrían ser suficientes. No obstante, la mayoría de los programas cuya única documentación es el código, se quedan obsoletos rápidamente y es imposible mantenerlos. El que la dedicación de un poco de esfuerzo a la documentación sea recompensado incluso dentro de los límites de un pequeño proyecto, constituye una sorpresa para la mayoría de los novatos.


     A menos que usted sea infalible y viva en un mundo en el que nada cambia, tendrá que volver a consultar el código que ya está escrito, y pondrá en duda decisiones que tomó durante el desarrollo del mismo. Si no documenta sus decisiones, se verá siempre cometiendo los mismos errores y tratando de comprender lo que pudo haber descrito fácilmente en una ocasión. La falta de documentación no sólo genera trabajo adicional, sino que también tiende a dañar la calidad del código. Si no posee una nítida caracterización del problema, es imposible que desarrolle una solución clara.

    Aprender a documentar software es una tarea complicada y exige un criterio de ingeniería maduro. Documentar de forma concisa es un error habitual, pero el otro extremo puede resultar igual de perjudicial: si escribe documentaciones extensas, éstas atosigarán al lector y constituirán una carga a la hora de conservarlas. Es esencial documentar sólo los asuntos correctos. La documentación no sirve de ayuda para nadie si su extensión desanima a la gente a la hora de leerla.

     Los principiantes tienen la tentación de centrar sus esfuerzos en temas sencillos, ya que éstos les resultan más fáciles de documentar. Esto es una pérdida de tiempo; no se aprende nada del esfuerzo y se termina escribiendo una documentación que es cualquier cosa excepto útil. Los principiantes también tienden a mostrarse reacios con los problemas de documentación. Esto trae consigo poca visión de futuro: si usted sabe que algún aspecto de su diseño no es del todo correcto, que alguna parte del problema no se ha aclarado o que es posible que parte del código tenga errores, ¡dígalo! Hará que el lector ahorre tiempo dándole vueltas a algo que aparentemente es erróneo, se acordará de dónde tiene que mirar si encuentra problemas y acabará teniendo una documentación más útil y honesta.

     Otro asunto es cuándo documentar. Aunque algunas veces es conveniente posponer la tarea de la documentación mientras se realizan experimentos, los programadores con experiencia suelen documentar de forma metódica incluso el código provisional, los análisis de un problema inicial y los borradores de un diseño. Ellos creen que esto hace que la experimentación sea más productiva. Además, dado que han tomado la documentación como hábito, les resulta normal documentar a medida que van avanzando.

     Este blog facilita directrices sobre cómo documentar un sistema de software. Proporciona una estructura esquemática y algunos elementos obligatorios, pero deja bajo su propio criterio todo lo referente a los detalles. Es esencial que no piense que la documentación es un asunto rutinario y aburrido; si lo hace, su documentación no servirá para nada y será penosa a la hora de leerla y escribir. Así que documente de forma consciente: pregúntese a medida que lo hace, por qué lo hace y si está empleando su tiempo de la forma más eficaz.

    
Esquema

    Su documentación debería tener la siguiente estructura. Se facilita un número de páginas orientativo; lo que presentamos a continuación son directrices, no un requisito:




 - Documentación de Requisitos

  - Documentación de Diseño

 - Documentación de Pruebas

- Reflexion 

- Apendice

- Documentación del Codigo

- Manuales de Usuario 






Requisitos


     La sección de requisitos describe el problema que se está solventando junto con la solución. Esta sección de la documentación resulta interesante tanto para los usuarios como para los implementadores; no debería contener detalles sobre la estrategia de implementación en concreto. Las otras partes de la documentación del sistema no serán de interés para los usuarios, únicamente para los implementadores, los encargados del mantenimiento y demás personal.







  1. Visión general (hasta 1 página) Una explicación del objetivo del sistema y de la funcionalidad del mismo.
  2. Especificación revisada. Si le facilitaron especificaciones detalladas del comportamiento del sistema, es probable que encuentre que ciertas partes del mismo se encuentran infraespecificadas o son ambiguas. En esta sección debería aclarar tanto cualquier suposición que haya hecho sobre el significado de los requisitos, como cualquier extensión o modificación de los mismos.
  3. Funcionamiento (1/2 página). ¿Qué recursos necesita el sistema para una operación normal y qué espacio y tiempo se espera que consuma?
  4. Análisis del problema (2 - 10 páginas). Una descripción clara del problema subyacente. Esto incluye el modelo conceptual que hay detrás del diseño (y posiblemente la interfaz de usuario), si no se ha tratado ya. El análisis del problema generalmente incluye uno o másmodelos de objeto del problema, definiciones de sus conjuntos y relaciones y una discusión de asuntos complicados. Los objetos en los modelos de objeto del problema proceden del dominio del problema, no del código. Los modelos de objeto deberían incluir tanto diagramas como cualquier restricción textual fundamental, y deberían estar claramente expuestos para una correcta legibilidad. Esta parte también debería describir alternativas que hayan sido consideradas pero que se han rechazado, con razones, asuntos no resueltos o aspectos que no hayan sido totalmente aclarados y que vayan a solventarse más tarde.
       
       Puede que los casos de uso le resulten útiles cuando escriba la especificación revisada y/o el manual de usuario. Un caso de uso es un objetivo específico y una lista de acciones que un usuario lleva a cabo para conseguir dicho objetivo. Un cliente puede, entre otras cosas, examinar la lista de acciones para decidir si la interfaz de usuario es aceptable. Si la colección de casos de uso abarca todos los objetivos deseados por el usuario, el cliente puede tener la seguridad de que el sistema cumplirá con su objetivo.

Diseño



          La sección de diseño de su documentación proporciona un cuadro de alto nivel de su estrategia de implementación.


  1. Visión general (1/2 - 3 páginas). Una visión general del diseño: organización de alto nivel, cuestiones de diseño especialmente interesantes, uso de librerías y otros módulos de terceros e indicadores de aspectos no resueltos o proclives al cambio. También incluye problemas con el diseño: decisiones que pueden resultar erróneas y los análisis de las consecuencias entre la flexibilidad y el funcionamiento que pueden ser juzgadas negativamente.
  2. Estructura en tiempo de ejecución (1 - 5 páginas). Una descripción de la estructura del estado del programa en ejecución, expresada como un modelo de objeto de código. Éste debería ocultar las representaciones de los tipos de datos abstractos; su propósito consiste en mostrar las relaciones entre objetos. Los modelos de objeto deberían incluir tanto diagramas como cualquier restricción textual fundamental, y deberían estar claramente expuestos para una correcta legibilidad. Las representaciones de los tipos de datos deberían explicarse (con sus funciones de abstracción e invariantes de representación) si esas representaciones son poco comunes, especialmente complejas o decisivas para el diseño global. Observe que las funciones de abstracción y los invariantes de representación deberían aparecer aún así en su sitio normal en el propio código.
  3. Estructura del módulo (1 - 5 páginas). Una descripción de la estructura sintáctica del texto del programa, expresada como un diagrama de dependencia entre módulos. Debería incluir la estructura del paquete y mostrar tanto las interfaces de Java™ del programa, calendario, material de clase, trabajos, exámenes, lecturas obligatorias, otras fuentes, prácticas, presentaciones, herramientas y proyectos, como las clases. No es necesario exhibir las dependencias de las clases en la API de Java™ del programa, calendario, material de clase, trabajos, exámenes, lecturas obligatorias, otras fuentes, prácticas, presentaciones, herramientas y proyectos. Su MDD (diagrama de dependencia entre módulos) debería estar claramente expuesto para una correcta legibilidad. Explique por qué se eligió esa estructura sintáctica en particular (ej.: introducción de interfaces para el desacoplamiento: qué desacoplan y por qué), y cómo se utilizaron los patrones de diseño concretos.
     Para explicar la descomposición y otras decisiones de diseño, exponga que aportan simplicidad, extensibilidad (facilidad para añadir características nuevas), particionalidad (los distintos miembros del equipo pueden trabajar en las diferentes partes del diseño sin necesidad de mantener una comunicación constante) u objetivos similares relativos a la ingeniería de software.

Pruebas


   

 
      La sección de pruebas de su documentación indica el enfoque que usted ha elegido para verificar y validar su sistema. (En un sistema real, esto podría incluir tanto las pruebas de usuario para determinar la idoneidad del sistema como solución al problema descrito en la sección de requisitos, como la ejecución de suites de prueba para verificar la corrección algorítmica del código). Del mismo modo que no debería comunicar el diseño de su sistema presentando el código o incluso enumerando las clases, no debería únicamente enumerar las pruebas realizadas. En vez de hacer esto, explique cómo se seleccionaron las pruebas, por qué éstas bastaron, por qué un lector debería creer que no se ha omitido ninguna prueba importante y por qué debería creer que el sistema realmente funcionará como se desee cuando se ponga en práctica.
  1. Estrategia (1 - 2 páginas). Una explicación de la estrategia general de las pruebas:blackbox y/o glassboxtop down (de arriba hacia abajo) y/o bottom up (de abajo hacia arriba), tipos de test beds (bancos de prueba) y manejadores de tests que se han utilizado, fuentes de datos del test, suites de prueba, métrica de cobertura, comprobación en tiempo de compilación frente a sentencias en tiempo de ejecución, razonamientos sobre su código, etc. Es posible que quiera usar técnicas distintas (o combinaciones de técnicas) en las diferentes partes del programa. Justifique sus decisión en cada caso.
Explique qué tipo de errores espera encontrar (¡y cuáles no!) con su estrategia. Comente qué aspectos del diseño dificultaron o facilitaron la validación.
  1. Resultados del test (1/2 - 2 páginas). Resumen de qué pruebas se han realizado y cuáles no, si es que queda alguna: qué módulos se han probado, y si se han probado a fondo. Indique el grado de confianza del código: ¿Qué tipo de defectos se han eliminado? ¿Cuáles son los que podrían quedar?

Reflexión

      La sección de reflexión (vulgarmente conocida como "post mortem") del documento es donde puede hacer generalizaciones partiendo de éxitos o fallos concretos, hasta llegar formular reglas que usted u otros puedan utilizar en el futuro desarrollo de software. ¿Qué fue lo que más le sorprendió? ¿Qué hubiera deseado saber cuando comenzó? ¿Cómo podría haber evitado los problemas que encontró durante el desarrollo?
  1. Evaluación (1/2 - 1 páginas). Lo que usted considere éxitos o fracasos del desarrollo: problemas de diseño no resueltos, problemas de funcionamiento, etc. Identifique cuáles son los rasgos importantes de su diseño. Señale técnicas de diseño o implementación de las que se sienta especialmente orgulloso. Explique cuáles fueron los errores que cometió en su diseño y los problemas que causaron.
  2. Lecciones (0,2 - 1 página). Qué lecciones ha aprendido de la experiencia: cómo podría haberlo hecho de otra forma una segunda vez, y cómo los errores de diseño e implementación pueden corregirse. Describa qué factores causaron problemas, como hitos errados, o errores y limitaciones conocidos.
  3. Errores y limitaciones conocidos. ¿De qué manera su implementación no llega a alcanzar la especificación? Sea exacto. Aunque perderá puntos por errores y características no presentes, obtendrá puntos parciales por identificar de manera exacta esos errores y el origen del problema.

Apéndice



     El apéndice contiene detalles de bajo nivel acerca del sistema, que no son necesarios para comprenderlo en un nivel superior, pero que se exigen para usarlo en la práctica o para verificar afirmaciones realizadas en cualquier parte del documento.
  1. Formatos. Una descripción de todos los formatos adoptados o garantizados por el programa: para un fichero E/O (fichero para entrada y salida de datos), argumentos de la línea de comando, diálogos de usuario, formatos de los mensajes para las comunicaciones en red, etc. Éstos deberían desglosarse en formatos visibles para el usuario, que son parte conceptual de los requisitos visibles para el usuario y del manual de usuario, y en formatos interiores que constituyen una parte conceptual de otros componentes de su documentación.
  2. Especificaciones del módulo. Debería extraer las especificaciones de su código y presentarlas por separado aquí. Si escribe sus comentarios en el estilo aceptado por Javadoc con el doclet de 6.170 , podrá generar documentos de la especificación de forma automática a partir del código. La especificación de un tipo abstracto debería incluir su visión general, campos de la especificación e invariantes abstractas (restricciones de especificación). La función de abstracción y el invariante de representación no forman parte de la especificación de un tipo.
  3. Casos de prueba. Idealmente, su banco de pruebas lee tests de un archivo de casos de prueba en un formato que resulta cómodo de leer y escribir. No es necesario que incluya casos de prueba muy extensos; por ejemplo, simplemente podría observar el tamaño de una entrada aleatoria generada para realizar pruebas de estrés y proveer al programa que generó los tests. Indique cuál es la utilidad de cada grupo de tests (ej. "pruebas de estrés, entradas enormes", "pruebas de partición, todas las combinaciones de +/-/0 para argumentos enteros").