Parte 1: ¿Por qué molestarse?
From The Joel on Software Translation Project
Especificación funcional sin dolor
Parte 1: ¿Por qué molestarse?
Por Joel Spolsky
Lunes 2 de Octubre de 2000
Artículo original: Painless Functional Specifications - Part 1: Why Bother?
Traducido por: Matías Bellone
Cuando se publicó por primera vez el test de Joel, uno de los puntos débiles más reportado por los usuarios tenía que ver con la redacción de especificaciones. Pareciera que las especificaciones son como utilizar hilo dental: todos saben que deberían hacerlo pero nadie lo hace.
¿Por qué la gente no escribe especificaciones? La gente dice que es por que se ahorran tiempo al saltearse la fase de redacción de una especificación. Actúan como si la redacción de la misma fuese un lujo reservado a los ingenieros espaciales de la NASA o a quienes trabajan para una compañía de seguros gigante y bien establecida. Excusas. Primero, no escribir una especificación es el más grande e innecesario riesgo que se puede correr en un projecto de sofware. Es tan estúpido como lanzarse a cruzar el desierto de Mojave con sólo la ropa en la espalda esperando abanicarse con ella. Los ingenieros de software que se sumergen en código sin escribir una especificación tienden a pensar que son vaqueros modernos disparando al galope. No lo son. Son terriblemente improductivos. Esciribrán mal código, producirán programas de poca calidad y amenazará sus proyectos corriendo riesgos que son totalmente innecesarios.
Creo que en cualquier proyecto no trivial (más de una semana de programación o más de un programador), sin una especificación siempre se desperdiciará más tiempo y se creará código de menor calidad. He aquí el porqué.
La función más importante de una especificación es diseñar el programa. Aún si uno está por sí mismo trabajando en código propio y se escribe una especificación para beneficio personal, el acto de redactar una especificación - describir el funcionamiento del programa con detalle - te forzará a realmente diseñar el programa.
Visitemos a dos programadores imaginarios en dos compañías. Rápido, en Software Bananas al Paso, jamás escribe especificaciones. "¿Especificaciones? No necesitamos estúpidas especificaciones". Al mismo tiempo, el señor Rogers en la compañía Software de Carácter, se niega a escribir código antes de que la especificación esté totalmente terminada. Éstos son sólo dos de tantos de mis amigos imaginarios.
Rápido y el señor Rogers tienen una cosa en común: ambos están a cargo de garantizar compatibilidad con versiones anteriores para la versión 2.0 de sus respectivos productos.
Rápido decide que la mejor forma de proveer dicha compatibilidad es programar un conversor de archivos de la versión 1.0 a archivos de la versión 2.0. Comienza atacando el problema directamente. Tipeo, tipeo, tipeo. Más tipeo, más tipeo y más tipeo. El disco duro gira. Polillas. Luego de dos semanas, contamos con un conversor razonable. Pero los clientes de Rápido no está contentos. El código de Rápido forzará a todos en la compañía a actualizar a la versión 2.0 al mismo tiempo. El cliente más grande de Rápido, Alcolicos S.A., se niega a comprar el nuevo programa; necesitan saber que la versión 2.0 será capaz de trabajar con archivos de la versión 1.0 aún sin convertir archivos. Rápido decide desarrollar un desconversor y vincularlo a la función de "Guardar". Es un poco complicado, porque cuando se utiliza una funcionalidad de la versión 2.0, parece hacerlo, hasta que se desee guardar el archivo en formato 1.0. Sólamente se avisa que la funcionalidad utilizada hace media hora no trabajará en el viejo formato de archivos. Por lo que el desconversor toma otras dos semanas en ser desarrollado y no funciona del todo bien. Tiempo transcurrido: 4 semanas.
Por su parte, el señor Rogers en la compañía Software de Carácter ("CaractSoft" para los conocidos) es uno de esos ñoños organizados que se niegan a escribir código hasta que se tenga una especificación. Se toma 20 minutos en diseñar una funcionalidad de compatibilidad de la misma forma que Rápido hizo y construye una especificación que dice, básicamente:
AL abrir un archivo creado con una versión anterior del producto, el archivo es convertido al nuevo formato.
Se muestra la especificación a los clientes que dicen: "¡Momento! No queremos actualizar a todos al mismo tiempo". El señor Rogers piensa un poco más y corrige la especificación de la siguiente forma:
Al abrir un archivo creado con una versión anterior del producto, el archivo es convertido al nuevo formato en memoria. Al guardar el archivo, se le da al usuario la opción de convertirlo. Pasaron otros 20 minutos.
El jefe del señor Rogers, un loco de los objetos, observa esto y piensa que algo no está del todo bien. Sugiere una arquitectura diferente.
El código será factorizado para utilizar dos interfaces: V1 y V2. V1 contendrá todas las funcionalidades de la versión 1.2 y V2, que es heredera de V1, agregará las nuevas funcionalidades. Por lo que V1::Guardar, puede manejar la compatibilidad mientras que V2::Guardar puede ser utilizado para guardar todo lo nuevo. Si se abre un archivo V1 y se intenta utilizar una funcionalidad de V2, el programa puede advertirlo inmediatamente y se ofrecerá convertir el archivo u olvidar la nueva funcionalidad.
20 minutos más.
El señor Rogers está molesto. La refactorización tomará 3 semanas en lugar de las 2 semanas que estaban planeadas originalmente. Pero soluciona todos los problemas de los clientes elegantemente, por lo que se sienta y lo hace.
Tiempo total transcurrido para el señor Rogers: 3 semanas y una hora. Tiempo total transcurrido para Rápido: 4 semanas, y el código no es tan bueno.
La moraleja de la historia es que, con un ejemplo hecho a medida, se puede probar lo que sea. Ups. No, eso no es lo que quise decir. La moraleja de la historia es que el diseñar el producto en un lenguaje humano, sólo toma unos minutos pensar en muchas posibilidades, revisar y mejorar el diseño. Nadie se siente mal cuando se borra un párrafo en un procesador de texto. Pero cuando se diseña un producto en un lenguaje de programación, toma semanas hacer un diseño interactivo. Lo que es peor, el programador que acaba de pasar 2 semanas escribiendo código estará apegado a dicho código sin importar cuán mal esté. Nada de lo que puedan decir el jefe de Rápido o sus clientes lo convencerá en tirar su hermoso código de conversión, aún cuando no represente la mejor arquitectura. Como resultado, el producto final tiende a ser un obstáculo entre el (incorrecto) diseño inicial y el diseño ideal. Fue "el mejor diseño que pudimos obtener, dado que ya habíamos escrito una gran porción que no queríamos tirar". No suena tan bien como "el mejor diseño que pudimos obtener, punto".
Esa es la gigante razón número 1 para escribir una especificación. La razón gigante número dos es para ahorrar tiempo de comunicación. Al redactar una especificación, sólo se debe comunicar una vez cómo se supone que trabajará el programa. Todos en el equipo sólo deben leer la especificación. La genten encargada de calidad la leerán para saber cómo debe funcionar el programa y qué es lo que deben probar. La gente de mercadeo la utilizarán para escribir sus vagos esbozos de vaporware en sitios web acerca de productos que no han sido creados aún.La gente de desarrollo empresarial la interpretará a su voluntad para crear locas fantasías sobre cómo el producto curará la calvicie y las arrugas, lo que sea que consiga inversores. Los desarrolladores la leerán para saber qué código deben escribir. Los clientes la leerán para asegurarse que los desarrolladores estén construyendo un producto por el que están dispuestos a pagar. Los redactores técnicos la leerán para redactar un bonito manual (para que se pierda o se tire a la basura, pero eso es otra historia). Los gerentes la leerán para que parezca que saben qué está sucediendo en las reuniones de directorio. Y así...
Cuando no se tiene una especificación toda esta comunicación sigue ocurriendo, porque debe ocurrir, pero sucede como sale. La gente de calidad juega con el programa a tontas y a locas y, cuando algo parece fuera de lugar, interrumpen a los programadores una vez más para preguntar algo estúpido sobre cómo se supone que debería de funcionar algo. Aparte de que esto arruina la productividad de los programadores, los programadores tienden a responder lo que corresponde a lo que dice su código en lugar de la "respuesta correcta". Por lo que la gente de calidad realmente estarán probando el programa contra sí mismo en lugar de el programa contra el diseño que sería, creo, un poco más útil.
Cuando no se ha redactado una especificación lo que sucede con los redactores técnicos es lo más gracioso (en una forma medio triste). Por lo general éstos redactores no tienen la torpeza de interrumpir a los programadores. En muchas compañías, si los redactores técnicos se acostumbran a interrumpir a los programadores para pregutar sobre cómo se supone que algo debería funcionar, los programadores le lloran a sus gerentes lo poco que pueden avanzar con el proyecto debido a estos [censurado] redactores para que los mantengan alejados. Y, los genentes, en un intento de mejorar la productividad, prohiben a los redactores desperdiciar más del preciado tiempo de sus programadores. Siempre se puede saber cuáles son estas compañías porque sus manuales y archivos de ayuda no proveen ningún tipo de información que no sea obvia al mirar la pantalla. Cuandose ve una pantalla con un mensaje que dice:
¿Deseas activar el soporte LRF-1914?
Y se hace click en "Ayuda", aparece un tema tragicómico rezando algo como:
Permite seleccionar entre soporte LRF-1914 (por defecto) o no utilizar el soporte LRF-1914. Si se desea soporte LRF-1914 haga click en "Sí" o presione "S". Si no desea soporte LRF-1914 haga click en "No" o presione "N".
Hm, gracias? Es bastante obvio aquí que el redactor técnico intentó cubrir el hecho que no sabían realmente qué siginigica soporte LRF-1914. No podían preguntarle a los programadores porque (a) es vergonzoso ó (b) el programador está en Kualalumpur y ellos están en Londres ó (c) la gerencia les prohibió interrumpir a los programadores ó cualquier otra de las innumerables patologías corporativas. Pero el problema fundamental es que no hubo especificación alguna.
La razón gigante número tres para tener una especificación es que, sin ella, es imposible hacer una planificación. No tener planificación alguna está bien si se trata de tu doctorado y planeas demorarte 14 años en él, o si eres un programador trabajando en el próximo Duke Nukem que saldrá cuando esté listo y bueno. Pero para casi cualquier negocio real, simplemente necesitas saber cuánto tardarán las cosas porque desarrollar un producto tiene un costo. Si no comprarías un pantalón sin saber cuál es su precio, ¿cómo se puede pensar que un negocio responsable puede decidir si contruir un producto o no sin saber cuánto tardará y, consecuentemente, cuánto costará? Para más sobre planificaciones, lean Planificación de software sin dolor.
Un terrible y común error es debatir sobre cómo algo debe ser diseñado y luego nunca finalizar el debate. Biran Valentine, el principal desarrollador de Windows 2000, era famoso por su lema: "decisiones en 10 minutos o menos, o la próxima es gratis".
En demasiadas organizaciones de programación, cada vez que hay un debate de diseño, nadie puede tomar una decisión por razones políticas por lo general. Por lo que los programadores no sólo trabajan en cosas simples y libres de controversias. A medida que pasa el tiempo, todas las decisiones difíciles son arrastradas hasta el final. Éstos son los proyectos con más posibilidades de fallar. Si estás comenzando una nueva compañia sobre una nueva tecnología y notas que son incapaces de tomar decisiones, bien podrías abandonar todo y devolver el dinero a los inversores porque no lanzarán nada.
Redactar una especificación es una excelente manera de fijar todas esas irritantes decisiones de diseño, las pequeñas y las grandes, que se esconden sin una especificación. Inclusive las pequeñas decisiones pueden ser resuletas con una especificación. Por ejemplo, si se está construyendo un sitio web con membresías, todos pueden acordar que si un usuario olvida su contraseña, se le enviará un e-mail. Genial. Pero eso no es suficiente para escribir el código. Para escribir el código se necesitan saber qué dirá ese e-mail. En la mayoría de las compañías no se puede confiar a los programadores la redacción de un texto que el usuario final debería ver (por buenas razones generalmente). Por lo que una persona de mercadeo o relaciones públicas o graduado en letras es más idóneo para que se le pregunte por el contenido de dicho mensaje: "Estimado ignorante, aquí está la contraseña que olvidó. Intente no ser tan descuidado en el futuro". Cuando uno se fuerza a redactar una especificación buena y completa (ya hablaré bastante de ese tema), notarás todas estas cosas y las solucionarás o, al menos, las marcarás con una gran bandera roja.
Bien. Estamos en el mismo punto del camino ahora. Las especificaciones son madres y pasteles. Sospecho que la mayor parte entiende esto y mis divagaciones, si bien entretenidad, no están enseñando nada nuevo. ¿Entonces porqué la gente no escribe especificaciones? No es para ahorrar tiempo porque no ahorra nada, y creo que la mayor parte de los programadores reconocen esto (en la mayoría de las organizaciones las únicas especificaciones son notas que un programador esbozó en una carilla luego de haber escrito el código y haberle explicado esa maldita funcionalidad a cada uno individualmente).
Creo que se debe a que a demasiada gente no le gusta escribir. Comenzando con una página en blanco es horriblemente frustrante. Personalmente, supero mi miedo a escribir tomando un curso que requería una composición de 3 a 5 páginas por semana. La escritura es un músculo. Mientras más se escriba más serás capaz de escribir. Si necesitas escribir una especificación, comienza un diario, una bitácora, inscríbete en un curso de redacción creativa o simplemente escribe una carta amable a cada familiar y compañero que hayas evitado en los últimos cuatro años. Cualquier cosa que incluya poner palabras en un papel mejorará tus habilidades para escribir una especificación. Si eres un gerente de desarrollo de software y quien se supone que debería estar escribiendo la especificación no lo está haciendo, envíalos a uno de esos cursos de redacción creativa de dos semanas en las montañas.
Si nunca has trabajado en una compañía que haga especificaciones funcionales, tal vez nunca hayas visto una. En la próxima parte de esta serie mostraré una especificación corta como ejemplo para que veas y discutiremos qué necesita tener una buena especificación. ¡Sigue leyendo!.
