archivo

Archivo de la etiqueta: requisitos funcionales

En el desarrollo de software los extremos no son buenos. A veces se le da al programador un diseño tan detallado que básicamente lo que hace es traducirlo a código fuente en el contexto del framework con el que trabaja. Otras veces no existe diseño o bien las especificaciones no son completas y son los programadores solos o en colaboración con analistas los que rellenan los huecos.

Desde mi punto de vista es importante que el programador sepa lo que tiene que hacer, es decir, que las especificaciones las conozca y que también conozca los objetivos no funcionales pero sobre esa base es necesario darle libertad para que dentro de esas restricciones pueda realizar la solución que resulta más conveniente.

Es necesario tener en cuenta que si se realiza un desarrollo en base a un análisis y/o diseño que se realizó hace tiempo es muy posible que quien lo hiciera no tuviera en cuenta determinados factores que sí son conocidos en el presente y no resulta lógico no echar cuenta a una solución mejor por tener en cuenta un trabajo que se efectuó sin conocer determinados tipos de detalles.

También es importante precisar que ese margen de maniobra permite que el programador dentro de esas restricciones pueda expresar su creatividad (algo que todos llevamos dentro) y realice su trabajo más motivado, algo que todos sabemos termina produciendo resultados de mayor calidad.

Como siempre es importante evaluar el contexto. No hay verdades absolutas. Es posible que en determinadas situaciones tener un nivel de detalle importante resulta fundamental, por ejemplo, cuando se externaliza a otro equipo de trabajo las tareas propias de programación de un desarrollo (o parte de él), aunque incluso en estos casos hay que tener en cuenta que la comunicación seguirá siendo necesaria (y se debe considerar un problema si no la hay) porque siempre quedará algún detalle que no se ha especificado al 100%.

Se tiene en mente que un producto equivocado es aquel que no cumple las especificaciones funcionales del área usuaria, sin embargo, podemos encontrarnos con aplicaciones que satisfaciendo eso son productos equivocados. ¿Qué cómo es posible eso? Pues todos esos sistemas que son inmanejables (mala experiencia de usuario y/o baja productividad de uso), que tienen infinidad de errores (o los suficientes para hacerlo insufrible)o que tienen otro tipo de deficiencias no funcionales relevantes.

Por eso cuando se esté definiendo un producto no solo se debe hacer desde el punto de vista funcional también hay que tener en cuenta y mucho la visión no funcional. La suma de una cosa y la otra son las expectativas del usuario (si bien hay cierta parte no funcional que no valorará, al menos, de primera mano) y todos sabemos que lo más complicado de capturar.

Me gusta mucho la siguiente cita de Mike Cohn porque refleja un riesgo real existente en todos los proyectos de desarrollo de software y que no se valora como se debiera (tal vez por el hecho de que se piensa de que siempre se va a acertar con el resultado): “El error más crítico en la mayoría de los proyectos es el riesgo de desarrollar el producto equivocado. Pese a eso este riesgo es prácticamente ignorado en la mayoría de los proyectos”.

Precisamente porque ese riesgo existe es otra de las razones que empujan a pensar que en la mayoría de los proyectos el enfoque más adecuado para su desarrollo es el iterativo e incremental a ser posible con ciclos cortos y visto desde una perspectiva ágil.

Las expectativas del usuario y la calidad del software están muy por encima de las especificaciones funcionales, por eso que el producto final termine satisfaciendo el catálogo de requisitos funcionales (por mucho que se hayan refinado) no asegura ni el éxito del producto ni su calidad final.

Si solo pensamos en requisitos funcionales estamos limitando nuestra visión sobre lo que debe ser el producto final. Cada uno puede tener una definición de lo que considera calidad del software, en la mía no es condición suficiente la verificación de los requisitos funcionales (y probablemente muchos de vosotros estéis de acuerdo conmigo). Son importantes, no digo lo contrario, pero no es lo único.

Por un lado tenemos las expectativas que, si bien podría englobar los aspectos funcionales, contiene ingredientes adicionales como son la experiencia de usuario y la productividad en el uso de la herramienta (muy ligado a la anterior).

Y por otros los requisitos no funcionales (algunos de ellos serán detectados de manera temprana por los usuarios y podrían afectar a las expectativas del usuario sobre el producto), como por ejemplo, la mantenibilidad (deuda técnica), la disponibilidad, el rendimiento, los recursos que requiere y consume, etc…

Pocas reflexiones pueden describir mejor en pocas palabras la realidad evolutiva del software que la realizó Jeff Sutherland, creador junto a Ken Schwaber de la metodología Scrum: “Los usuarios no saben lo que quieren hasta que lo ven y siempre se reservan el derecho a cambiar de opinión”.

Es cierto que hay técnicas que ayudan a afinar en los requisitos, como son los prototipos, pero por muy bien que estén hechos, hasta que no lo utilizan (voy más allá del hecho de que lo vean) no terminan de dar las indicaciones necesarias para que el producto satisfaga sus expectativas.

Esto nos lleva a un enfoque iterativo incremental en el desarrollo de software, como modelo de referencia para ajustarnos a esta realidad.

Es la evolución natural de los desarrolladores que han trabajado con el ciclo de vida clásico o en cascada y de las organizaciones que han venido utilizando esa metodología.

Está comprobado que la cascada no produce buenos resultados ya que se ajusta a un modelo ideal de desarrollo de software en el cual las especificaciones de los usuarios son las adecuadas (para lo cual el usuario tiene que tener perfectamente claro qué es lo que quiere y cómo lo quiere ver plasmado en un sistema de información y, por otro, que el equipo de proyecto capte de la mejor manera posible esas expectativas) y que no cambian durante el proceso de diseño y construcción.

El desarrollo de software tiene una naturaleza adaptativa, evolutiva, no predictiva y por tanto el ciclo de vida en cascada no se ajusta a ese patrón.

Por ese motivo, el primer paso que suelen dar los desarrolladores y organizaciones habituados a ese esquema de desarrollo es dividirlo en fases y convertirlos en desarrollos incrementales. El siguiente paso que se suele dar es revisar al final de cada fase las desviaciones respecto a las expectativas, de manera que se tenga en cuenta para la siguiente fase la cual además de funcionalidades nuevas tendrá los desarrollos necesarios para realizar los ajustes de la fase anterior, pasándose de esta forma a un ciclo de vida iterativo incremental.

Una vez llegado a ese punto el salto a una metodología ágil es cuestión de tiempo.

Los requisitos funcionales y no funcionales de un sistema de información determinan el mapa inicial de lo que los usuarios esperan del sistema. Se trata de una predicción sobre lo que que quieren y que después tendrán que constrastar con el producto final.

Lo normal es que exista una diferencia entre una versión de un producto y lo que se esperaba de ella, por lo que después son necesarios mecanismos de ajustes que disminuyan esa distancia a unos umbrales razonables o que la eliminen. Lo ideal es que esa diferencia sea la menor posible y los analistas funcionales y orgánicos y los responsables de codificar el proyecto intenten que así sea, sin embargo los proyectos de desarrollo de software están sometidos a muchos factores que afectan negativamente a ese objetivo.

En cualquier caso, los requisitos representan necesidades y expectativas de los usuarios y es necesario, por tanto, conocerlos y tenerlos en cuenta como referencia en el desarrollo del producto software.

Por tanto, este área de proceso requiere que los requisitos estén perfectamente identificados y, además, sean conocidos y entendidos por todos los implicados en el proyecto (equipo de proyecto, usuarios, responsable técnicos del cliente, etc…).

Otro de los requerimientos de este área es que se tenga control sobre el cambio en los requisitos, para ello es necesario que solo un grupo reducido de personas tengan la capacidad de decidir en ese sentido.

Esto no quiere decir que cualquier usuario no pueda proponer cambios, antes al contrario, cualquier aportación debe ser acogida de forma positiva, el matiz en este caso, es que esas propuestas deben ser analizadas por unos pocos (que se entienden que son designados como expertos del proceso o procesos que se informatizan) y que con el asesoramiento de los técnicos software (sería lo más recomendable) toman la decisión sobre qué cambios realizar, cuáles no y en definitiva, cuáles son las prioridades.

Ante una decisión de cambio en los requisitos, este área de proceso tiene el requerimiento de que el resto de artefactos/entregables del proyecto se mantengan consistentes.

Por este motivo hay que tener mucho cuidado a la hora de definir los entregables documentales de un proyecto, ya que cuántos más y más complejos sean, mayor será el esfuerzo necesario para ponerlos consistentes. Es importante apoyarse en herramientas CASE para facilitar la consecución de este objetivo.

Otro requerimiento es la trazabilidad bidireccional y sobre esto habría mucho que hablar. Si se toma al pie de la letra quiere decir que debería poder conocer todos los componentes de ingeniería del software y del producto software (a nivel de clase) asociados a un requisito y también en el sentido contrario, es decir, que partir de una clase se sepa a qué requisito o requisitos puede afectar un cambio en la misma. El objetivo de esto es poder realizar un análisis de impacto y servir también de soporte para la detección de inconsistencias entre los requisitos y los productos derivados del proyecto (incluido el propio sistema de información).

Sin embargo, esta trazabilidad bidireccional resulta costosa de conseguir y no resultaría aconsejable su aplicación en determinados tipos de proyectos (se estaría matando moscas a cañonazos) y en otros, llegar a nivel de clase en el código no aportaría mucho ya que la organización en capas, de las clases, etc… viene condicionada por el generador de código utilizado y el framework.

Para poder respectar en lo posible este objetivo, es importante definir un nivel de entregables documentales acordes a la naturaleza del proyecto (maś entregables, más complejidad, así que hay que tener cuidado con esto) y tener un conocimiento del framework de desarrollo y de la arquitectura de la aplicación, de manera que se sepa de manera rápida donde hay que mirar para conocer el impacto de la modificación de determinados requisitos (lo que se hace es mirar de más arriba la codificación de la aplicación y no entrar a un detalle a nivel de clase). También resulta fundamental un código lo más claro y limpio posible.

Sobre la trazabilidad lo importante, entiendo que debe ser quedarse con el espíritu de la misma y tener unos procedimientos en el proyecto que permitan hacer un análisis de impacto y análisis de consistencia en un tiempo razonable. Hay que recordar que CMMI establece un modelo de referencia, determina el qué pero no el cómo.

Soy de la opinión de que en el desarrollo de software los requisitos funcionales y de interfaz de usuario deben quedar resueltos antes de empezar a codificar, sin embargo hay ciertos aspectos que no cobran su verdadera forma hasta que uno se enfrenta a su programación, hasta que se siente el código.

Sentir el código, es una cita que leí a Alex Bergonzini en su Twitter y desde luego no le falta razón ya que en la programación se enfoca el problema.

Martin Fowler también le da importancia a sentir el código en su siguiente reflexión (traducción libre): “Cuando te sientas a escribir código, aprendes cosas a las que no puedes llegar en el proceso de modelado… ya que hay un proceso de feedback al que solo puedes llegar desde la ejecución de determinadas funcionalidades y viendo como funcionan”.

El desarrollo de software es adaptativo y todo no se puede prever, a veces hay que experimentar hasta encontrar una solución satisfactoria para el usuario, eso es totalmente compatible con los desarrollos ágiles. Ahora bien, el hecho de que los principios ágiles indiquen que no hay que elevar ninguna funcionalidad a definitiva no quiere decir que todo deba ser consecuencia de la experimentación, porque construir y tirar módulos software además de ser caro puede provocar una desmotivación importante en el equipo de proyecto.