miércoles, 6 de agosto de 2014

Diseñar y Programar Pensando en el Cambio

¡Hola! Hoy quería compartir con ustedes mi experiencia, sobre todo técnica, en el manejo de los Pedidos de Cambios que se dan en los Proyectos de Desarrollo de Software. Fundamentalmente, sobre cómo diseñar y programar una Aplicación para que no se hunda en el caos absoluto ante el primer Pedido de Cambio que debamos implementar sobre la misma.

 

Primero y Antes Que Nada… ¿Qué es un Cambio?

 

clip_image002[4]

Según la Real Academia Española (RAE), un Cambio puede definirse como la “Acción y efecto de cambiar”. Bien, entonces nos preguntamos, ¿qué es cambiar? Pues bueno, también según la RAE, Cambiar puede definirse como “Dejar una cosa o situación para tomar otra”.

Si bien ésta es una buena aproximación teórica, aún dista bastante del concepto que tenemos en nuestra profesión acerca de lo que es un cambio.

En el mundo del Desarrollo de Software, lo solemos entender de otra forma: un Cambio es un pedido, generalmente formal, que suele realizar el Cliente y a través del cual solicita modificar un Requerimiento previamente definido, o bien añadir uno nuevo al Backlog de Tareas, de acuerdo a un conjunto de necesidades, correcciones, mejoras y/o restricciones que hayan surgido a posteriori de haber relevado y acordado el Requerimiento original.

 

El Proceso de Gestión de Cambios

Teniendo en mente el Proceso de Gestión de Cambios y de cómo construir aplicaciones con una mayor flexibilidad para incorporar cambios, vale la pena aclarar algo: al desarrollar Software, siempre estará latente la posibilidad de que surjan modificaciones en el transcurso del Proyecto, ya que los Requerimientos, como toda necesidad, distan mucho de permanecer estáticos en el tiempo.

No podemos negar esta realidad, pero sí podemos estar preparados para gestionarlos de la mejor forma posible y ser conscientes de la necesidad de diseñar una aplicación que sea robusta y permeable a los cambios con el objetivo de minimizar los impactos negativos que estos pudieran ocasionar en otras áreas o módulos de la misma.

Retomando la definición que habíamos presentado en el punto anterior, cada uno de estos pedidos que nos suelen llegar de nuestros Clientes, los cuales pueden ser formales o no tanto (a veces sucede que el Cliente no los manifiesta explícitamente o lo hace por vías informales, como por ejemplo, en una charla de pasillo), los solemos conocer como “Solicitudes de Cambio” o “Pedidos de Cambio”, y están soportados por un procedimiento formal, estructurado y bien documentado que permite gestionar los diferentes estadios de los cambios, desde que los mismos se originan hasta que son cerrados o descartados. Este procedimiento lo solemos conocer como Proceso de Gestión de Cambios.

A grandes rasgos, y sin entrar en detalles en lo que es la Gestión de Proyectos, podemos identificar las siguientes etapas dentro de lo que es el Ciclo de Vida de un Pedido de Cambio:

· Registración del Pedido de Cambio

· Realización de un Análisis de Impacto (de gestión, funcional y técnico)

· Negociación y Acuerdo del Pedido de Cambio con el Cliente

· Aprobar, rechazar, modificar o posponer la Implementación del Pedido de Cambio

· Desarrollo e Implementación del Pedido de Cambio, en el caso de que el mismo sea aprobado

· Validación y Verificación del correcto funcionamiento de la Aplicación, tomando como punto de partida el Análisis de Impacto realizado previamente

Es imprescindible, en el caso de que un Pedido de Cambio sea aprobado, que el mismo sea comunicado a todos los miembros del equipo involucrados en el proyecto, de forma que estén al tanto del asunto, ya que puede suceder que deban revisarse otros módulos de la Aplicación, o que haya que cambiar un estándar o simplemente que genere incompatibilidades con algo que ya tenemos hecho.

Si el equipo no es notificado oportunamente, va a seguir trabajando con supuestos que puede que ya no sean válidos y que eventualmente como consecuencia se produzcan más cambios en cadena en un futuro no muy lejano.

 

¿Con Qué Tipos de Cambios Podemos Encontrarnos?

clip_image004[4]Determinar todos los cambios posibles que podrían surgir en un proyecto dado es algo inviable, ya que, por un lado, deberíamos conocer al mínimo detalle las especificaciones funcionales y no funcionales del proyecto; y por el otro, el Cliente, el Usuario y todos los involucrados en el Proyecto deberían tener identificadas absolutamente todas sus necesidades y mantenerlas estáticas a lo largo del tiempo.

No obstante, lo que sí podemos conocer y determinar son las diferentes dimensiones que poseen los cambios, lo cual nos va a servir para catalogarlos, preverlos y gestionarlos en el transcurso del proyecto. De todas las dimensiones que existen, en este artículos nos vamos a centrar únicamente en tres de ellas: los Orígenes, los Motivos y los Tipos de Pedidos de Cambios, las cuales nos van a proveer ciertas pautas que deberemos tener en cuenta a la hora de diseñar y programar una solución pensando en los cambios.

En lo que respecta a la dimensión Orígenes de los Pedidos de Cambios, podemos encontrar las dos siguientes fuentes:

· Internos, que es cuando los cambios surgen dentro del mismo Equipo de Desarrollo de la Aplicación. En estos casos, no siempre se lo suele involucrar al Cliente.

· Externos, que es cuando los cambios son planteados por el Cliente, el Usuario Final o algún Área vinculada al proyecto (como por ejemplo los Departamentos de Arquitectura, de Seguridad o de Change Management).

Por otro lado, en la dimensión Motivos de los Pedidos de Cambios solemos encontrar tres razones que pueden dar surgimiento a los cambios:

· Nuevas Necesidades y/o Restricciones, que no se hayan contemplado en el relevamiento inicial de los requerimientos, y que generalmente serán planteadas por el mismo Cliente o el Usuario Final.

· Mejoras, producto de ajustes que haya que realizarle a la Aplicación en pos de mejorar el rendimiento de la misma, la usabilidad por parte del usuario, la interacción con otros sistemas, etc.

· Correcciones, originadas principalmente por errores en la Especificación y/o en la Construcción de la Aplicación. Comúnmente los solemos conocer con los nombres de Bugs, Issues o Incidentes.

Y por último, podemos encontrar la dimensión Tipos de Pedidos de Cambio, que suele estar más asociada al impacto que un cambio genera en los requerimientos originales:

· Pedidos de Cambios Funcionales, los cuales están asociados a los Requerimientos Funcionales de la Aplicación, es decir, a las funciones que debe realizar la Aplicación, al comportamiento interno que debe tener el Sistema.

· Pedidos de Cambios No Funcionales, los cuales están asociados a los Requerimientos No Funcionales, más que nada a los Atributos de Calidad del Software. Si bien hoy en día aún existen algunas discrepancias entre los diferentes referentes del tema, a grandes rasgos podemos encontrar las siguientes subcategorías de Requerimientos No Funcionales: Funcionalidad, Flexibilidad, Usabilidad, Eficiencia, Mantenibilidad y Portabilidad.

 

¿Cómo Hacer Que Mi Aplicación Sea Más Permeable a los Cambios?

Entonces, tomando en cuenta todo lo anterior, desde nuestra perspectiva más técnica ¿existe algo que podamos hacer, ya sea en el armado de la arquitectura, en el diseño de un módulo o en la programación de una funcionalidad, para que al llegar un Pedido de Cambio se minimice el impacto negativo de su implementación?

Definitivamente, la respuesta es sí. Sí podemos tomar acciones tempranas que nos ayuden a diseñar y construir una Aplicación preparada para recibir cambios en un futuro; es decir, que sean flexibles a las modificaciones y robustas en el sentido de que dicha Aplicación no se rompa al tener que alterar una funcionalidad o módulo de la misma.

A continuación, vamos a enumerar algunas recomendaciones que podremos tener en cuenta en las diferentes etapas de diseño y construcción de una Aplicación para que, llegado el momento de tener que implementar uno o más cambios, logremos mitigar el riesgo y reducir el impacto negativo de la tarea:

· Como primer punto, al pensar y diseñar la Arquitectura de la Solución, deberemos tener en cuenta que la misma tiene grandes probabilidades de ir sufriendo modificaciones conforme avancemos en el proyecto. Es fundamental que entendamos que la Arquitectura es dinámica, y que debe ser lo primero que sea adaptable al cambio en un Sistema.

· Consensuar la Arquitectura con el equipo de trabajo, y si lo hubiera, también con el equipo técnico del Cliente. De esta forma nos vamos a asegurar de tener un mejor diseño de entrada, antes de comenzar con el grueso de las tareas de construcción de la Aplicación.

· Siempre se deberá plantear la Solución de forma Modular, identificando las diferentes Áreas de la Aplicación y tratar de lograr un bajo acoplamiento entre áreas independientes. Si hubiera que integrar una o más áreas, una buena técnica es utilizar Interfaces que nos abstraigan de los detalles de la implementación particular de cada una de ellas.

· Es importante identificar los Módulos Core de la Solución, que son aquellos que van a ser utilizados por el resto de los Módulos de la Aplicación (como por ejemplo los Módulos de Seguridad, Permisos, Logueo de Errores, Configuración, Exportación de Datos, etc.), y dotarlos de las interfaces necesarias para garantizar una buena integración sin exponer demasiados detalles de su implementación interna.

· Por otro lado, también es importante identificar las capas que van a formar parte de nuestra Aplicación (por ejemplo las Capas de Interfaz de Usuario, de Servicios de Negocio, de Acceso a Datos, etc.) y definir y comunicar las responsabilidades que cada una de ellas va a tener, de forma de organizar mejor el código y las funciones que se deberán construir.

· Vinculado al punto anterior, es sumamente importante que la lógica de negocio esté concentrada en un único lugar, llámese área, capa o módulo. Por ejemplo, si definimos que va a haber una Capa de Negocios, entonces sólo deberá haber Lógica de Negocio en dicha capa. Esto debe ser respetado por todo el equipo, ya que la Lógica de Negocio es el ítem que más Pedidos de Cambio deberá soportar a lo largo de un Proyecto. Lamentablemente es bastante común, especialmente en proyectos grandes, encontrar con el paso del tiempo Lógica de Negocio desperdigada por toda la Solución, lo que finalmente termina derivando en mayores esfuerzos y riesgos a la hora de tener que aplicar un cambio sobre determinada funcionalidad.

· Definir y comunicar estándares de construcción y codificación, de forma de mantener homogénea la Solución. Esto es importante ya que si un miembro del equipo debe aplicar un cambio en un módulo que él no programó, al menos el código y el estilo de construcción le resulte familiar y se minimice el riesgo de introducir errores.

· Ante cambios complejos o con un impacto alto, es recomendable agregar comentarios en el código que expliquen el por qué fue necesario el cambio y un resumen acerca de lo que se realizó. Si bien esto debería agregarse también en el Changeset, es más fácil y útil tenerlo a mano en el código por si es necesario realizar un ajuste posterior.

· Ya sea que estemos desarrollando una Aplicación Web o Desktop, es fundamental que hagamos una clara separación entre el Layout de las Pantallas y la lógica que les da soporte a las mismas. Si el ítem que suele sufrir mayor cantidad de Pedidos de Cambios es la Lógica de Negocio, el segundo lugar es para los Aspectos Visuales (Look & Feel) de la Aplicación. Es más sencillo y menos riesgoso hacer las modificaciones si los componentes se encuentran correctamente separados.

· Relacionado con lo anterior, por ejemplo, si estamos trabajando en una Aplicación Web, deberemos construirla desde un comienzo pensando en separar la estructura de las páginas (en los archivos HTML), de la forma en la que se van a visualizar (en los archivos CSS), y de la lógica de cliente que pudieran tener (en los archivos Java Script).

· En el caso de WPF, por citar un ejemplo, es posible emular el manejo de estilos trabajando con Resource Dictionaries e importarlos en cada una de las pantallas que conforman la Aplicación. Otras tecnologías modernas de Interfaz de Usuario también ofrecen alternativas que nos permiten desacoplar la lógica de la estructura de los aspectos visuales de las pantallas.

· Definir y utilizar una buena herramienta de Software Configuration Management (SCM), no sólo como repositorio de código fuente, sino también para gestionar el Ciclo de Vida de los Pedidos de Cambio. Una de las mayores ventajas es que al utilizar una única herramienta podremos lograr una trazabilidad entre Pedido de Cambio/Impacto/Modificaciones en la Aplicación que nos permitirán evaluar y corregir eventuales incidencias que se originen a futuro como consecuencia de la implementación de un cambio determinado.

· Si tenemos que implementar un Cambio con un Impacto alto, es una buena práctica hacerlo en un Branch aparte, de forma de mantener controlado el Impacto y no afectar al resto del equipo hasta que el mismo se haya implementado e integrado total y correctamente al resto de la Aplicación.

· Otra buena práctica, para asegurarnos que la implementación de un cambio no generará comportamientos no deseados en el actual funcionamiento de la Aplicación, será contar con un buen conjunto de Unit Tests, los cuales podremos ejecutar a demanda para verificar que todo siga funcionando correctamente luego de haber realizado las modificaciones.

· Extendiendo el concepto del punto anterior, aún mejor sería contar con Tests Automáticos y un Servidor de Integración Continua, para que de esta forma podamos validar en todo momento el estado de la Aplicación. Además, un buen Servidor de Integración Continua nos ofrecerá reportes, estadísticas, y nos avisará cuando algo falle en la Aplicación para que lo corrijamos inmediatamente antes de continuar con nuestras tareas.

Bueno, la anterior es sólo una pequeña lista con ideas que podemos tomar para lograr que nuestra Aplicación pueda incorporar cambios más fácilmente, armada desde mi experiencia y de lo que sugieren las Buenas Prácticas de Desarrollo de Software. Los invito a colaborar para completarla, proponiendo ideas que desde su experiencia nos ayuden a lograr aplicaciones más permeables a los cambios, flexibles y robustas.

Obviamente, si bien el hecho de tener en cuenta los puntos anteriores no nos va a garantizar el éxito al tener que implementar los cambios que vayan surgiendo en el proyecto, sí nos va a ayudar a mitigar los impactos negativos que pudieran llegar a ocurrir en este proceso.

Por último, y ya despidiéndome de ustedes quería dejarles un pequeño chiste de Dilbert, alegórico al tema central de este artículo. Espero que les guste J

clip_image006[4]

 

¡Gracias Ariel Bensussan por tu contribución!