Sunteți pe pagina 1din 7

El pozo de alquitrán

No hay escena de la prehistoria que refleje tanto como la lucha de las grandes bestias en
el pozo de alquitrán. En su mente uno ve dinosaurios, mamuts, tigres diente de sable que luchan
con la fuerza del alquitrán. Cuanto más fuerte es la lucha, mas enreda el alquitrán, y no hay bestia
tan fuerte o tan habilidosa que puede escapar, por lo tanto se hunden.
El desarrollo de grandes aplicaciones ha sido en la ultima década este pozo, y grandes y
poderosas bestias han caído violentamente en el. La mayoría han emergido con sistemas
funcionando, pocas han logrado los objetivos, planes y presupuestos. Grandes y pequeños,
masivos o compactos, todos los equipos se han hundido en el pozo. No parece ser a causa de la
dificultad – cada garra puede ser sacada-. Pero la acumulación de factores simultáneos e
interactivos hace más lento al movimiento. Todos parecen sorprendidos por la rigidez del
problema, y es difícil discernir la naturaleza del mismo. Pero debemos tratar de entenderlo para
poder resolverlo. Por lo tanto comenzaremos a identificar el arte del desarrollo de sistemas, lo que
se disfruta y lo que se padece del mismo

El producto del desarrollo de sistemas


Ocasionalmente uno lee en el diario notas sobre como dos programadores en un garage
remodelado construyeron un programa que sobrepasa los esfuerzos de grades equipos. Todo
programador está preparado para creer en esos cuentos, el piensa que puede construir cualquier
programa más rápido que las 1000 líneas/año reportadas por los grandes equipos de desarrollo.
Por qué entonces no todos los grandes equipos de desarrollo han sido reemplazados por
dúos de garage? Uno debe mirar que es lo que se está produciendo.
El programa A. Esta completo en si mismo, listo para ser ejecutado por el autor en el
entorno donde fue desarrollado. Eso es lo que comúnmente se realiza en los garajes, y eso es el
objeto que el programador individual usa para estimar productividad.
Hay dos formas en las que un programa puede ser convertido en algo más útil, pero más
cotoso. Estas dos maneras son representadas por las líneas del diagrama.
Yendo hacia abajo a través de la línea vertical, un programa se vuelve un producto de
programación, este es un programa que puede ser ejecutado, testeado, reparado y extendido por
cualquiera. Se puede usar en entornos, para muchos conjuntos de datos. Para volverse un
producto de programación de uso general, debe estar en una forma genérica. En particular el
rango y forma de las entradas debe ser general tanto como lo permita el algoritmo. Luego el
programa debe ser probado de forma exhaustiva, de forma tal que sea confiable. Esto significa
que se deben escribir una gran cantidad de casos de prueba que permitan explorar el rango de
entradas y probar los límites, los mismos deben ser ejecutados, guardados y registrados.
Finalmente la promoción de un programa a producto de programación requiere una
documentación exhaustiva, para que cualquiera pueda usarlo, arreglarlo y aplicarlo. Estimando a
dedo, cálculo que un el costo de un producto de programación es tres veces mayor que un
programa debuggueado con la misma funcionalidad.
Atravesando la línea horizontal, un programa se convierte en un componente de un
sistema. Esto es una colección de programas que interactúan, coordinados por funcionalidad en
una forma ordenada, de forma tal que constituye un servicio para grandes tareas. Para volverse
un componente de un sistema, un programa debe ser escrito para que cualquier entrada y salida
cumpla con una sintaxis y una semántica, y que posea interfaces bien definidas. El programa
también debe ser diseñado para que solo use un limitada cantidad de recursos (espacio de
memoria, dispositivos de entrada/salida y tiempo de CPU). Finalmente, el programa debe ser
testeado con otros componentes del sistema con todas las combinaciones esperadas. Estas
pruebas son muchas porque el número de combinaciones crece exponencialmente. Consume una
gran cantidad de tiempo por errores sutiles provenientes de interacción inesperada de los
componentes en prueba. Un componente de un sistema cuesta por lo menos tres veces más que
un programa con la misma funcionalidad. El costo puede ser aun mayor si el sistema tiene
muchos componentes.
El producto de un sistema, difiere de un simple programa en todo sentido. Cuesta por lo
menos nueve veces mas. Pero este es verdaderamente útil, el producto esperado de todos los
esfuerzos del desarrollo de sistemas.

1
La diversión del desarrollo
El adulto disfruta construir cosas, especialmente de su propio diseño, disfrutando de la
construcción de cosas, también está el placer de hacer cosas que son útiles a otros.
Profundamente, uno quiere que otros usen nuestro trabajo y lo encuentren útil. Tercero está la
fascinación por encajar objetos complejos y observarlos trabajar en ciclos. Pudiendo jugar con su
funcionamiento. Cuarto esta la diversión de aprender, que nace de la naturaleza no repetitiva de la
tarea. De una forma u otra el problema es siempre nuevo, y su solución enseña algo: a veces
practico, a veces teórico y en ocasiones ambos.
Finalmente, esta el disfrute de trabajar en ese predecible medio. El programador, como el
poeta trabaja solo con cosas que salen de su mente. Construye castillos en el aire, de aire, solo
usando su imaginación. Pocas formas de construcción son tan flexibles, tan fáciles de pulir y
rehacer, tan capaces de la realización de grandes estructuras conceptuales.
Sin embargo, el desarrollo de software, a diferencia de las palabras del poeta, es real en el
sentido de que se mueve y trabaja, produce resultados visibles independientes de su
construcción. Imprimen resultados, dibuja imágenes, produce sonidos, mueve brazos. La magia
de los mitos y las leyendas se volvió realidad en nuestro tiempo.
Programar es entonces divertido porque satisface anhelos creativos arraigando en
nosotros y enaltece visibilidades que tenemos en común todos los hombres.

Los padecimientos del desarrollo


Primero, uno debe desempeñarse perfectamente. La computadora reencarna la magia de
las leyendas en este sentido también. Si un carácter, una pausa, del hechizo no está en su debida
manera, la magia no funcionará. Los seres humanos no están acostumbrados a ser perfectos, y
muy pocas áreas de la actividad humana lo demandan. Ajustarse al requerimiento de la perfección
es, creo, la parte más difícil de aprender a programar.
Luego, otras personas establecen los nuestros objetivos, nos proveen de nuestros
recursos y nos proporcionan nuestra información. Uno raramente controla las circunstancias de su
trabajo o incluso su meta. En términos de administración nuestra propia autoridad no es suficiente
para nuestra responsabilidad. Esto se muestra en todos los campos, sin embargo, en los trabajos
donde las cosas se han hecho, nunca la autoridad formal estuvo en consonancia con la
responsabilidad. En la práctica, la autoridad real (opuesta a la formal) es obtenida en el momento
de los logros.
Depender de otros es una situación especialmente dolorosa para un programador.
Depende de programas de otros. Estos usualmente están mal diseñados, pobremente
implementados, entregados sin terminar (sin fuentes y/o casos de prueba) y pobremente
documentados. Así que el debe gastar horas estudiando y corrigiendo cosas que un mundo ideal
ya estarían completas, disponibles y usables.
El siguiente problema es que diseñar grandes conceptos es divertido; encontrar pequeños
bugs es solo trabajo. Con cualquier actividad creativa se llega la punto en que las horas de trabajo
se vuelven tristes y dolorosas, y la programación no es la excepción.
Luego uno encuentra que depurar tiene una convergencia lineal, o peor, cuando uno
espera una forma de forma de aproximación cuadrática al final. Por lo tanto a medida que el
testing avanza, toma mas tiempo hallar los últimos bugs que los primeros.
El ultimo padecimiento, y algunas el colmo, es que el producto sobre el cual uno trabajo
por tanto tiempo parece volverse obsoleto cuando se lo termina (o incluso antes). Los colegas y
competidores ya están en plena búsqueda de nuevas y mejores ideas. El pensamiento de un niño
no es solo concebido sino además planeado.
Esto siempre parece peor de lo que en realidad es. El producto más nuevo y mejor
generalmente no está disponible cuando uno completa el suyo; solo esta discutido. Este también
requerirá meses de desarrollo. El tigre de papel nunca será igual a uno de carne y hueso, salvo
que realmente se lo requiera.
Por supuesto que la base tecnológica sobre la que uno construyes esta en constante
avance. Tan pronto como uno congela un diseño, se vuelve obsoleto en su concepto. Pero la
implementación de los productos reales demanda separar en fases y analizar cantidades. La
obsolescencia de una implementación debe ser comparada contra otras implementaciones
existentes, no contra conceptos todavía no desarrollados. El desafío y la misión es encontrar
soluciones reales a problemas reales con planes realizables utilizando los recursos disponibles.
2
El mítico mes/hombre
Muchos más proyectos han fracasado por la falta de tiempo que por el resto de las causas.
¿Por qué esta es la causa de desastres más común?
Primero, nuestras técnicas de estimación están muy pobremente desarrolladas. Mas serio
aún, reflejan la asunción implícita de que todo irá bien cuando en realidad esto no es así.
Segundo, nuestras técnicas de estimación confunden, de forma errónea, esfuerzo con
progreso, escondiendo la asunción que los hombres y los meses son intercambiables.
Tercero, porque no estamos seguros de nuestras estimaciones, normalmente los
managers carecen de la cortesía y testarudez del chef de Antoine1.
Cuarto, el avance del plan es pobremente monitoreado. Las técnicas de rutina ya probadas
en otras áreas de la ingeniería son consideradas innovaciones radicales en el desarrollo de
software.
Quinto, cuando se descubre un retraso en el plan, la reacción natural (y tradicional) es
agregar gente. Es como apagar un fuego con nafta, esto empeora mucho las cosas. Más fuego
requiere más nafta, esto genera un ciclo que culmina en un desastre.
El monitoreo del avance del proyecto será el asunto de otro ensayo. Consideremos otros
aspectos del problema con mayor detalle.

Optimismo
Todos los programadores son optimistas. Quizás esta sociedad moderna atrae
especialmente aquellos que creen en finales felices y hadas madrina. Quizás las cientos de
frustraciones han ahuyentado a aquellos que habitualmente se concentran en el objetivo final.
Quizás simplemente es que las computadoras son jóvenes, los programadores son jóvenes y los
jóvenes son siempre optimistas. Pero sin importar como funcione el proceso de selección, el
resultado es irrefutable: “Esta vez seguro que ejecuta”, o “Acabo de encontrar el último bug”.
Entonces la primera falsa suposición en la que se basa todo plan de desarrollo de sistemas
es que todo irá bien, ejemplo, cada tarea tomará el tiempo que fue estimado para ella.
La perseverancia del optimismo entre los programadores demanda mas que un simple
análisis. Dorothy Sayers, en su excelente libro, The Mind of the Maker, divide a la actividad
creativa en tres etapas: la idea, la implementación, y la interacción. Un libro, una computadora o
un programa vienen a este mundo en primer lugar como una idea, construidos fuera del tiempo y
del espacio, usando birome, tinta y papel. La creación está completa cuando alguien lee el libro,
usa la computadora o ejecuta el programa, recién ahí está interactuando con la mente del
constructor.
Está descripción, la cual Sayers usa para iluminar no solo a la creatividad humana sino
también a la doctrina Cristiana de la Trinidad, nos ayudará en nuestra tarea actual. Para los
fabricantes de cosas, las incompletitudes e inconsistencias de nuestras ideas se vuelven claras
solo durante la implementación. Esa es la razón por la cual escribir, experimentar y probar son las
disciplinas esenciales para el teórico.
En muchas actividades creativas nos es posible interactuar con el medio de ejecución. La
madera se parte, la pintura se corre, los circuitos eléctricos zumban. Estas limitaciones físicas del
medio restringen las ideas, y también crean dificultades inesperadas en la implementación.
La implementación, entonces, toma tiempo y sudor por culpa de las limitaciones físicas y
las incompatibilidades de las ideas subyacentes. Tendemos a culpar al medio físico de la mayoría
de nuestras dificultades en la implementación.
El desarrollo de software, sin embargo, crea un medio extremamente flexible. El
programador construye solo desde entes ideales: conceptos y representaciones muy flexibles de
los mismos. Como el medio es tan flexible, esperamos pocas dificultades en la implementación, he
aquí la razón de nuestro constante optimismo. Como nuestras ideas tienen fallas, tenemos bugs,
por lo tanto nuestro optimismo es injustificado.
En una sola tarea, la suposición de que todo irá bien tiene un efecto probabilístico en la
planificación. Puede que se realice como fue planeada, a partir de allí está la probabilidad de que
nos encontremos con una demora, y “nada de demora” tiene una probabilidad finita. Un gran

1
Nota del autor: Al comienzo de este capitulo hay una foto de un menú del restaurante Antoine. Fred Brooks hace
hincapié en la siguiente frase escrita en dicho menú: “La buena cocina toma tiempo. Si está dispuesto a esperar, es para
servirlo mejor, y para satisfacerlo”

3
esfuerzo de programación consiste en muchas tareas, algunas encadenadas de punta a punta. La
probabilidad de que cada una vaya bien se vuelve demasiado chica.

El mes/hombre
La segunda falla radica en la única unidad de esfuerzo usada para estimar y planificar: el
mes/hombre. El costo del producto varía en función de la cantidad de personas y la cantidad de
hombres. El progreso no. El hecho que mes/hombre es una unidad para medir el tamaño de un
trabajo es un mito peligroso y engañoso. Implica que hombres y meses son intercambiables.
Los hombres y los meses son intercambiables solamente cundo una tarea puede ser
dividida entre muchos hombres sin comunicación entre ellos. Es verdad para cortar carne o
cosechar algodón, pero no ni siquiera está cerca de serlo para el desarrollo de sistemas.
Figura 1. Tiempo versus trabajadores para una tarea perfectamente particionable.

Cuando una tarea no puede ser dividida debido a restricciones secuenciales, la aplicación
de más esfuerzo no tiene efecto en el plan (Fig3). La gestación de un bebe tomas nueve meses,
no importa cuantas mujeres se asignen. Muchas tareas del desarrollo de software tienen esta
característica por la naturaleza secuencial de la depuración.
Figura 2. Tiempo versus cantidad de trabajadores para una tarea que no se puede dividir

En las tareas que se pueden dividir pero requieren comunicación entre las subtareas, el
esfuerzo dedicado a la comunicación debe ser agregado a la cantidad de trabajo a realizar. Por lo
tanto lo mejor que se puede hacer es menos que un simple intercambio entre hombres y meses
Fig 3. Tiempo vs cantidad de trabajadores en una tarea divisible que requiere comunicación

La carga que se agrega debido a la comunicación esta conformada por dos partes,
capacitación e intercomunicación. Cada trabajador debe ser capacitado en la tecnología, las
metas del esfuerzo, la estrategia y el plan de trabajo. Esta capacitación no puede ser dividida, por
lo tanto esta parte del esfuerzo agregado varía linealmente con el número de trabajadores.
La intercomunicación es aun peor. Si cada parte de la tarea debe coordinar con cada una
de las otras partes el esfuerzo se incrementa respetando la formula n(n-I)/2. Tres trabajadores
requieren tres veces más comunicación entre pares que dos; cuatro seis veces mas que dos. Si
además tiene que haber conferencias entre tres, cuatro, etc. trabajadores para resolver cosas en
conjunto, la cosa se pone peor. El esfuerzo agregado por la comunicación puede contrarrestar
completamente la división de la tarea original y llevarnos a la situación de la fig5.
Fig 4. Tiempo versus cantidad de trabajadores en una tarea con interrelaciones complejas

Como el desarrollo de SW es inherentemente un esfuerzo sistemático (un conjunto de


relaciones complejas) el esfuerzo dedicado a la comunicación es grande, y rápidamente domina la
disminución en el tiempo de las tareas individuales provocada por la división. Agregar mas gente
alarga, no achica, el tiempo del proyecto.

Prueba de sistemas
No hay partes de la planificación que se ven afectadas por restricciones de secuencialidad
como la depuración y la prueba del sistema. Más aun, el tiempo requerido depende de la cantidad
de errores encontrados. Teóricamente este número debería ser cero. Debido al optimismo,
usualmente esperamos que la cantidad de bugs sea menor a lo que al final termina siendo. En
consecuencia las pruebas son la parte que mas errores tienen en su planificación.
Por algunos años he usado la siguiente regla para planificar un proyecto de desarrollo de
software:
1/3 de análisis y relevamiento.
1/6 de codificación
¼ de pruebas de componentes y primeras pruebas del sistema
¼ de pruebas de sistema con todos los componentes en la mano.
Esto difiere de la planificación original en muchas maneras:
1. La parte asignado al análisis y relevamiento es mayor que lo normal. Aun así es
apenas suficiente para producir una especificación sólida, y no es suficiente para
incluir una investigación y/o exploración de todas las técnicas nuevas.
4
2. La mitad del cronograma dedicada a la depuración del código finalizados es mucho
mayor que lo normal.
3. A la parte más fácil de estimar, la codificación, solo se le asigna un sexto del
cronograma.
Examinando cronogramas convencionales, encontré que muy pocos asignaban la mitad
del mismo al testing, pero lo que realmente hacían era dedicar la mitad del tiempo real para ese
propósito. Muchos de estos casos no sufrieron atrasos hasta llegar a las pruebas de sistema.
El error de no asignar suficiente tiempo para las pruebas es un desastre muy peculiar.
Como el atraso surge al final del cronograma, nadie esta al tanto de esta demora hasta casi
llegada la fecha de entrega. Malas noticias, tarde sin ningún tipo de advertencia, es inquietante
para clientes y managers.
Más aun, un retraso en este punto tiene usualmente severas repercusiones psicológicas y
financieras. El proyecto esta lleno de personal y su costo por dia es altísimo. Mas serio aun, el
software se usa para soportar otras tareas del negocio y los costos secundarios de demorarlas
son muy altos, ya que estamos casi al momento de la entrega. Efectivamente, estos costos
secundarios pueden superar a los otros. Por esto es muy importante asignar suficiente tiempo
para las pruebas de sistema en el cronograma original.

Estimación débil
Nótese que para el programador, como para el chef, la urgencia del jefe puede dominar la
completitud de la tarea en tiempo, pero no puede dominar la completitud real. Un omelet,
prometido en dos minutos, puede aparentar progresar bien. Pero cuando no está listo en dos
minutos, el clientes tiene dos opciones: esperar o comerlo crudo. Los clientes de software tienen
las mismas opciones.
El cocinero tiene otra opción más, puede incrementar el calor. El resultado es comúnmente
un omelet sin nada para salvar, quemado en una parte, crudo en otra.
No creo que los managers tengan menos coraje y firmeza que los chef, tampoco creo que
sea así en managers de otras ingenierías. Pero realizar planes falsos para satisfacer las fechas
deseadas por el jefe es mucho más común en nuestra rama de la ingeniería. Es muy difícil hacer
una defensa fuerte creíble de una estimación que no esta derivada de ningún método
cuantitativos.
Claramente se necesitan dos soluciones. Necesitamos desarrollar y publicitar estadísticas
de productividad, estadísticas de incidencias, reglas de estimación. La profesión se verá
beneficiada al compartir esos datos.
Hasta que la estimación tenga una base más sólida, cada manager tendrá que levantar su
espalda y defender su estimación con la seguridad que sus pobres métodos son mejores que
estimaciones derivadas de deseos.

Desastre regenerativo de calendario


¿Qué es lo que uno hace cuando un proyecto se atrasa? Agregar gente, naturalmente.
Como muestran las figuras 2 a 5, esto puede ayudar o no.
Consideremes un ejemplo. Supongamos que una tarea esta estimada en 12
meses/hombre y se asigna a tres hombres en cuatro meses, y que hay cuatro hitos medibles A, B,
C, D, cada uno planificado para caer al final de cada mes (Figura 6).
Ahora supongamos que el primer hito no es alcanzado hasta dos meses después de lo
estipulado (Figura 7). ¿Cuáles son las alternativas que tiene el lider del proyecto?
1. Asumir que la tarea debe estar terminada a tiempo. Asumir que solo la primera
parte de la tarea estaba mal estimda, así la figura 7 cuenta la historia de forma
precisa. Entonces quedan nueve meses/hombre de esfuerzo y dos meses, por lo
tanto se necesitaran 5 personas. Agregar 2 personas a las tres ya asignadas.
2. Asumir que la tarea debe estar terminada a tiempo. Asumir que se estimo de
menos en forma pareja, entonces la figura 8 describe esta situación. Por lo tanto
quedan 18 meses/hombre de esfuerzo y dos meses, entonces se necesitan 9
personas. Agregar 6 personas a las tres ya asignadas.

5
Figura 5

Figura 6

Figura 7
3. Rehacer el plan, Me gusta el consejo que dio P. Fagg, un experimentado ingeniero
de hardware, “No tomar pequeños desvíos”. Eso significa, permitir suficiente tiempo

6
en el nuevo plan para asegurar que el trabajo puede ser terminado de manera
cuidadosa y robusta, asi no habrá que rehacer el plan nuevamente.
4. Cortar la tarea. En la práctica esto tiene a pasar de todas formas, una vez que el
equipo observa el defasaje. Cuando los costos secundarios de la demora son muy
altos, esta es la única alternativa posible.
En los primeros dos casos, insistir que la tarea debe ser completada en cuatro meses es
desastroso. Considerando los efectos regenerativos, por ejemplo, para la primera alternativa
(Figura 9). Las dos nuevas personas requerirán capacitación pro parte de una de las que ya esta
trabajando en el proyecto. Si esto toma un mes, 3 meses/hombre han sido dedicados para trabajo
que no estaba en la estimación original. Mas aun, la tarea originalmente dividida en tres caminos,
debe ser repartida en cinco partes, por lo tanto algo del trabajo ya realizado se perderá, y la
prueba de sistema sera mas lenta. Entonces al final del tercer mes, quedan 7 meses/hombre de
esfuerzo, 5 personas entrenadas y un mes disponible. Como la figura 9 sugiere, el producto esta
tan demorado como si nadie se hubiese agregado (Figura 7).
Mantener la esperanza de terminar en cuatro meses, considerando solo la capacitación,
sin dividir ni realizar pruebas extra, requerirá agregar 4 personas, no 2, al final del segundo mes.
Para cubrir la división y las pruebas del sistema, uno debería tener que agregar más gente. Sin
embargo uno tiene un equipo de por lo menos 7 personas; entonces los aspectos de organización
y división son de otras características, no solo una cuestión de cantidad.

Figura 8
Nótese que al fin del tercer mes las cosas se verán muy negras. El hito del primero de
Marzo no ha sido alcanzado a pesar de todo el esfuerzo del líder. La tentación es muy fuerte para
repetir el ciclo, agregando más gente todavía. Eso nos llevara al caos.
Para la asunción de que solo el primer hito estuvo mal estimado. Si el primero de marzo
uno hace la suposición que todo el cronograma fue optimista como en la figura 8, uno quiere
agregar 6 personas a la tarea original. El calculo de la capacitación, división y los efectos de las
pruebas de sistema lo dejo para el lector. Sin lugar a dudas, el desastre regenerativo dejará como
consecuencia un producto pobre.
Simplificando creamos la ley de Brooks:
Agregar mas gente al proyecto, lo hace terminar mas tarde.
Esta es la desmitificación del mes/hombre. El número de meses de un proyecto depende
de sus restricciones de secuencialidad. El número máximo de personas depende del número de
tareas independientes. De estas dos cantidades podemos deducir usar menos hombres y mas
meses (el único riesgo de estos es la obsolescencia). Uno no puede lograr cronogramas que
funcionen usando más gente y menos meses. Muchos más proyectos han fracasado por la falta
de tiempo que por el resto de las causas

S-ar putea să vă placă și