archivo

Archivo de la etiqueta: mantenimiento evolutivo

He insistido en diferentes artículos que gran parte de la suerte del proyecto se juega antes de que comience. Una mala negociación, una mala venta condiciona todo lo demás (pudiéndose partir de una situación de Death March Project) y solo produciéndose determinadas circunstancias ideales: un equipo de proyecto motivado y de calidad y un cliente y unos usuarios que facilitan las tareas, pueden paliar las pérdidas del proyecto, tangibles (en dinero), como intangibles (de pérdida de imagen con el cliente ante un proyecto de ejecución deficiente).

Sin embargo, la venta inicial del producto es solo una de las variables que condicionan el posterior desarrollo del proyecto, la elección de una mala metodología ya sea por parte del proveedor o impuesta por el cliente puede hacer estragos en el trabajo realizado, en el coste y en los resultados.

Lo mismo si no se delimita de manera adecuada el alcance (ya sea antes de la venta o antes incluso de empezar a recoger requisitos).

Y después toca el análisis. Si la metodología condiciona un desarrollo en cascada la realización de un análisis excelente es esencial, si bien, todo se puede ir al traste en el momento en que cambia algunas de las variables del proyecto (interlocutores, procesos, etc…) y es que los modelos predictivos tienen ese problema.

Si la metodología es ágil o al menos iterativa incremental (como RUP), las tareas de análisis también son de gran importancia, aunque desarrollos iterativos y evolutivos dan un mayor margen para la corrección de deficiencias en la captura e interpretación de los requisitos y en el modelado de la solución.

Por tanto, independientemente de que en función de la metodología aplicada la realización de un buen análisis tenga una mayor importancia, en todas condiciona el resto del proyecto y muchísimo.

Un mal análisis, si se detecta en etapas tardías (en muchos casos, cuando el producto ha llegado a producción), provocará un más que probable fracaso de la puesta en marcha del sistema y un más que probable esfuerzo económico importante para resolver esta circunstancia, mediante mantenimientos correctivos y evolutivos, que podrían ser incluso no asumibles si la deuda técnica del desarrollo es elevada.

Pero es que un mal diseño también tiene consecuencias y muy importantes en el resultado final del software.

Por eso destaco siempre que, además de contar con buenos programadores, disponer de buenos analistas funcionales y orgánicos permite que el trabajo de los que codifican brille más y sobre todo, sea útil.

De ahí la importancia de realizar testing desde el principio, fundamento este que dió lugar, por ejemplo a las metodologías de testing en V o en W.

En resumen, aunque muchos piensen que el partido se juega en la construcción del software, si no se han realizado de manera adecuada las etapas anteriores, el partido se habrá perdido antes de que el árbitro de el pitido inicial.

Quien esté libre de pecado que tire la primera piedra.

¿Nadie ha copiado y pegado código de Internet en su aplicación y ha hecho adaptaciones del mismo hasta que lo ha hecho funcionar?, ¿lo mismo solo que en lugar de Internet el código procede de otra aplicación de tu organización o en la que has participado previamente?.

Soy de la opinión de que en lo posible hay que intentar entender lo que se está haciendo porque si no es así, no tendremos completa seguridad, salvo que realicemos una buena batería de pruebas, de que realmente el código funciona. Además, si no lo entendemos y toca hacer una mantenimiento evolutivo del mismo, nos encontraremos con la misma situación de partida solo que ahora probablemente no tendremos código que copiar y adaptar.

A veces los plazos se nos echan encima, queremos quitarnos una tarea de cierta complejidad que realmente no tiene mucha importancia dentro del proyecto o hay algo que no nos termina de funcionar. Esto provoca que en ocasiones se busquen soluciones donde sea y se da lugar a esta práctica que todos sabemos que aunque pueda ser efectiva en ocasiones, no es nada positiva en el proceso de desarrollo de software.

Hay quien entiende esto como reutilización de código. Si se quiere reutilizar código, yo entiendo que lo mejor es utilizar la fórmula de las librerías, de las API (cuando se delega funcionalidades en terceros), ya que se tiene más controlado el software que se utiliza. También podría entender esto como reutilización de código si se comprende lo que se está haciendo, es decir, lo que se hace es ahorrar un trabajo que no va a aportar nada, que es pesado, que sabemos como hacerlo y que ya está hecho en otro proyecto.

Sobre copiar y pegar código de otras fuentes (en este caso Internet), el desarrollador Mike Johnson realiza la siguiente reflexión: “Copiar y pegar código de Internet en el código del programa es como masticar chicle que has encontrado en la calle”.

La respuesta la he obtenido en una cita anónima que dice que: “Cualquier programa que funciona correctamente está obsoleto”.

Es decir, la evolución del producto se puede extender a lo largo de todo su ciclo de vida porque en cualquier momento pueden aparecer nuevas funcionalidades que incorporar al sistema o la modificación de las ya existentes.

El desarrollo de software es así, evolutivo, cambiante y es importante que tengamos en cuenta ese aspecto a la hora de enfocar un proyecto, sobre todo si es complejo y/o de gran tamaño. También resulta fundamental la actitud pedagógica con la dirección de la organización y con otros departamentos para que tengan en cuenta este aspecto a la hora de designar los presupuestos para el Departamento TIC.

¿Cuántas veces hemos escuchado al usuario comentar qué por qué el sistema le solicita una información que ya se encuentra almacenada en el mismo o por qué no le proporciona información calculada que se podría obtener con los datos ya introducidos?

Quitando aquellos casos en los que el usuario se equivoca (porque realmente el sistema no tiene almacenado los datos que él pensaba) es un problema que se produce en muchas ocasiones y que se traduce en la necesidad de un mantenimiento evolutivo del sistema.

Un buen diseño de modelo de datos es muy importante ya que permite que los datos se almacenen de forma que su posterior recuperación o su utilización para devolver datos calculados sea lo más sencilla posible. Un mal diseño del modelo de datos provocará consultas complejas para obtener aquellos datos o información más utilizados en el sistema.

Pero tan importante resulta tener un buen diseño del modelo como conocerlo de manera adecuada. A lo largo de la vida de un sistema diferentes personas habrán participado en el diseño y si no se conoce de manera adecuada dará lugar a un redundancia de datos, un incremento de la complejidad del modelo, un manejo deficiente de los datos, etc…

Sobre esto hay una cita de Rick Lemmons que viene muy bien para exponer este caso: “No hagas que la interfaz de usuario proporcione información que el sistema ya sabe”.

No debería ser así porque realmente no hay nada que justifique que el software se tenga que ir deteriorando conforme se van realizando tareas de mantenimiento con el mismo. Sin embargo todos estamos hartos de ver gráficas con el número de errores de un software que llegado a un punto empiezan a crecer de nuevo de manera lenta, pero continua.

Algunos de los motivos pueden ser los siguientes:

– El software desarrollado tiene una importante deuda técnica lo que complica las tareas de mantenimiento.

– Se dispone de poco tiempo para poder realizar mantenimientos correctivos o evolutivos por lo que la consecuencia es eliminar el problema cuanto antes, lo que da lugar a parches que solucionan el problema pero incrementan la deuda técnica del producto.

– El software no para de crecer en funcionalidades incrementándose su complejidad.

Sobre el deterioro del software, Weinberg tiene la siguiente reflexión: “No hay un código tan grande, retorcido o complejo que el mantenimiento no puede empeorar”.

Las pruebas de aceptación son aquellas realizadas por los usuarios con carácter previo al paso a producción de una nueva versión del producto. Se trata de pruebas de caja negra en un entorno de preproducción en la que se verifican si las funcionalidades pactadas para la entrega y recogidas en catálogos de requisitos, casos de uso, historias de usuario u otro hito documental, cumplen las expectativas del usuario.

El problema de este tipo de pruebas es que en demasiadas ocasiones los usuarios (o sus jefes) rechazan invertir tiempo suficiente para realizar estas tareas de testing y en otras, los equipos de desarrollo tampoco ponen demasiado interés en ello.

En desarrollos siguiendo metodologías clásicas o en cascada si no se ha hecho participar al usuario en fases posteriores al análisis y no se han hecho ajustes, las pruebas de aceptación servirán para poco porque probablemente, salvo que el desarrollo sea de poco alcance, habrán variado las condiciones iniciales o bien el usuario se encontrará con una implementación que aún respetando los requisitos (que está por ver) será complicado que verifique lo que se imaginaba que iba a hacer el sistema.

Sin embargo en mantenimiento evolutivos o correctivos pequeños, ciclos de vida iterativos incrementales (con sprints de corta duración) o mediante la aplicación de metodologías ágiles, este tipo de pruebas sí que tendrían una gran utilidad porque se evita pasar evoluciones a producción que pueden afectar a un trabajo eficiente de los usuarios con la aplicación.

En los proyectos de desarrollo de software muchos usuarios (y directores usuarios) cargan sobre las espaldas de los responsables técnicos del proyecto mucho más que la gestión técnica del proyecto, desentendiéndose de muchas decisiones en el proceso de análisis y de casi todas las que proceden del día a día de un mantenimiento evolutivo.

Los que nos dedicamos a esto tenemos la costumbre de asumir ese trabajo por el bien del proyecto. Son tantos meses los que nos hemos llevado en el desarrollo que ya lo sentimos como nuestro y como además hemos aprendido buena parte del negocio pues además de la vertiente técnica nos vemos capaces de decidir sobre lo funcional.

El inconveniente de afrontar un desarrollo y un mantenimiento de esa manera es que por un lado, los responsables funcionales no valorarán de manera adecuada el trabajo que haces ya que si bien mantienes el proyecto funcionando no saben el esfuerzo que requiere y no aportarán al mismo los medios económicos que requieren. Por otro lado, al no ser ellos quienes deciden, dan manga ancha al conjunto de usuarios para que pidan continuamente cambios, en muchos casos de manera contradictoria y centrándose en aspectos dudosamente prioritarios.

Cuando en un proyecto se entra en la dinámica de que los responsables técnicos lleven el peso del mismo es muy complicado salir de ella, ya se sabe que las costumbres son complicadas de romper, por eso es importante dejar las cosas claras desde el principio, desde el mismo proceso de desarrollo y si se nota que los usuarios empiezan a desatender sus obligaciones, exponerlo.

Lo más importante en el proyecto de desarrollo de software son las personas (así lo establece el movimiento ágil y lo demuestra nuestra experiencia en este negocio), todos los que participamos en los proyectos independientemente del rol que juguemos en ellos. Todos aportamos y si alguna de las partes falla, los resultados se resienten.

En muchas ocasiones no se entra en esa dinámica de manera voluntaria, son los propios superiores en la organización los que toman la decisión de que se funcione de esa manera. Ante esto es complicado encontrar una solución. Lo importante es que si esto se produce nosotros hayamos advertido hasta el máximo nivel organizativo al que podamos llegar que esta situación va a perjudicar al proyecto y después que en lo posible, utilicemos nuestra propia habilidad para intentar conseguir toda la colaboración que sea posible de los usuarios.