26 marzo 2007

Calidad en programas pequeños

Cuando uno empieza a programar, muchas veces confunde un programa de calidad con un programa "vistoso". Por eso, voy a repasar algunos de los factores de calidad más frecuentes, y lo apoyaré con algún ejemplo aplicado a programas de pequeño tamaño (menos de 300 líneas de código, por ejemplo). Estos ejemplos en la mayoría de los casos los acercaré a lenguajes como C y C++.

Corrección
El programa es correcto si hace lo que el usuario quería que hiciera.
Un ejemplo: Tengo que calcular las soluciones de una ecuación de segundo grado. Aplico la fórmula x1 = (- b + sqrt(b*b - 4*a*c) ) / 2 * a ... Pero debería dividir entre (2*a), he olvidado un paréntesis, así que la solución es incorrecta. Si no hago suficientes pruebas (por ejemplo, sólo miro la ecuación x2 - 4 = 0), es fácil que se me escape.

Fiabilidad
El programa es fiable si se comporta correctamente, incluso en situaciones inesperadas. Esto incluye los casos en que los datos que recibimos no sean los correctos.
Ejemplo: ¿Qué hace mi programa si no existe el fichero de datos? ¿Y si el usuario teclea una texto en vez de un número?

Eficiencia
Un programa es eficiente si la cantidad de recursos y de código que necesita para realizar una función son razonables.
Ejemplo: voy a abrir un fichero de configuración, pero no sé manejar memoria dinámica, así que reservo espacio para 10.000 líneas... por si acaso.

Seguridad
Es el grado en el que se controla el acceso al programa o los datos por usuarios no autorizados.
Ejemplo: Mi programa tiene un interfaz web. ¿Puede un usuario entrar directamente a la pantalla de visualización de datos, sabiendo su URL, sin haber pasado antes por la pantalla de validación?

Facilidad de uso
Indica el esfuerzo necesario para aprender, manejar, preparar entradas e interpretar la salida de un programa.
Ejemplo: ¿Tiene el usuario información en pantalla sobre las teclas que debe usar? ¿Hay ayuda disponible? ¿Se puede salir pulsando ESC o hay que pulsar Ctrl+Alt+Mays+S?

Mantenibilidad
Es el esfuerzo requerido para localizar y corregir un error en un programa en funcionamiento (el programa debería ser fácil de leer, fácil de modificar)
Ejemplo: ¿Uso siempre variables de una sola letra, o nombres más significativos? ¿Pongo comentarios en lo que no es evidente? ¿Tengo funciones de 300 líneas o de 20 líneas? ¿Están disponibles los diagramas de diseño?

Facilidad de prueba
Es el esfuerzo necesario para probar un programa (cuando se quiere garantizar que realiza la función deseada).
Ejemplo: ¿He creado una función que recibe parámetros y devuelve resultados, de forma que pueda hacer pruebas repetitivas, contrastando los resultados obtenidos con resultados conocidos? ¿O está todo dentro de "main" y sólo puedo hacer pruebas tecleando valores?

Flexibilidad
Indica si es fácil modificar un programa que ya está en funcionamiento.
Ejemplo: si decido que la variable "contador" no debería ser un "int", sino un "long", ¿tendré que modificar muchas partes de mi programa?

Portabilidad
Es el esfuerzo requerido para trasferir un programa de una configuración hardware o entorno software a otro.
Ejemplo: He creado mi programa de prueba con Windows, que es lo que tengo en casa. ¿Funcionará en el Linux que hay instalado en mi centro de estudios, o he usado funciones exclusivas de Dos/Windows, como getch o clrscr?
Y otro caso "más profesional": voy a crear pequeño programa con interfaz gráfico. ¿Todos los usuarios lo manejarán siempre desde Windows? ¿O me puede interesar usar una biblioteca multiplataforma como Qt o Gtk, por si algún usuario prefiere (o necesita) usar Linux o MacOs X?

Reusabilidad
Es el grado en que lo que se ha desarrollado para un programa se puede utilizar en otras aplicaciones.
Ejemplo: Voy a hacer un programa parecido, pero con ciertas posibilidades nuevas. ¿Podré aplicar lo que he hecho o tendré que volver a crear muchas cosas que ya hice?

Interoperatividad
Es una medida del esfuerzo necesario para acoplar un sistema con otro.
Ejemplo: ¿Podré hacer que mi utilidad lea los ficheros de datos que manejaban las demás aplicaciones del sistema? ¿Y los ficheros de datos que genere se podrán manipular directamente desde aquellas? ¿Podré incluso pasar datos "al vuelo", sin necesidad de usar ficheros intermedios?


Como se puede ver, todo son "puntos a tener en cuenta", pero en la mayoría de los casos no existe una forma clara de "medir" hasta qué punto se ha conseguido aplicar un cierto criterio. Aun así, aunque no se pueda decir "ahora mi programa es el doble de portable que antes", deberíamos considerar estos puntos cuando programamos, para acercarnos a ese "programa de calidad" que pretendemos hacer.

Referencias (hay muchas fuentes de información en Internet; éstas son sólo por citar unas cuantas):

Breves notas sobre la Medición de los Atributos Externos del Software
http://www.sc.ehu.es/jiwdocoj/mmis/externas.htm

La importancia de las buenas prácticas en el desarrollo de aplicaciones Java
http://www.als-es.com/home.php?location=recursos/articulos/buenas-practicas-java

Aspectos de Calidad en el Desarrollo de Software Basado en Componentes
http://www.lcc.uma.es/~av/Publicaciones/02/CalidadDSBC.pdf

A Pattern Framework for Software Quality Assessment And Tradeoff
www.eelke.com/research/literature/SQTRF.pdf

Food for Thought: How Do You Define Software Quality?
www.swqual.com/newsletter/vol1/no4/vol1no4.html

1 comentario:

Carlos R. dijo...

Holap:

Estoy 100% de acuerdo con todo lo expuesto... xD

Saludooos :P