archivo

Archivos Mensuales: junio 2010

Hace unas semanas, un amigo me comentaba que le sorprendía como mucha gente codificaba como si nunca más se tuviera que volver a revisar o mantener el código que estaba programando, lo que provocaba la entrega de código no comentado, difícilmente legible o comprensible y lo que es peor, con mucha deuda técnica que hacía que el mantenimiento del mismo fuera a la vez complejo y costoso.

El programador tiene su culpa en todo esto y lo bien o mal que codifique será función de su experiencia, capacidad técnica y sobre todo de su implicación en el proyecto y de la conciencia de que el ciclo de vida del software no termina en la entrega, sino que después le queda un largo período de vida lleno de mantenimientos correctivos y evolutivos.

No obstante, por encima del programador, hay otros responsables que deben de dejar claro que la calidad del software para la empresa, no es una actividad secundario o la guinda del pastel, sino que es algo que debe ser inherente a los desarrollos de la organización, de manera que la calidad esté plénamente integrada en los procesos. Estos responsables son tanto los analistas funcionales, arquitectos y jefes de proyecto que deben supervisar y velar por el cumplimiento de unos estándares de calidad definidos y corregir cualquier actitud de los programadores y analistas programadores cuyo trabajo no respete esos estándares y si se persiste en dicha actitud tomar las medidas oportunas.

Se dice que la calidad del software va en contra de los costes del proyecto para el proveedor de los servicios de desarrollo de software. Yo no estoy de acuerdo, lo que va en contra de los costes es precisamente codificar sin tenerlo en cuenta, ya que tarde o temprano esa deuda técnica repercute contra el proveedor, ya sea durante el mismo desarrollo cuando se tengan que arreglar módulos de la aplicación con errores, durante la fase de garantía o durante la entrega del producto y puesta en marcha, donde esa falta de calidad traerá consigo un peor funcionamiento de la aplicación, un mantenimiento más costoso y una pérdida de confianza del cliente respecto al proveedor. Al final se tendrán flecos que no se terminan de cerrar y que son muchos más costosos que si se hubiera invertido el tiempo necesario para entregar un producto de mayor calidad o si se tuviera técnicos más cualificados para realizar dicho trabajo.

No cerrar entregas, no cerrar proyectos, son un peso terrible a soportar tanto por clientes como por proveedores de servicios de desarrollo de software. El problema no está solo en incumplir plazos, que ya de por sí es un problema serio, sino por el hecho de que no terminar de cerrar entregables es una carga adicional que se suma a la carga de las nuevas tareas que surgen, lo que hace que provoca que se tenga que dedicar maś tiempo a llevar dichos trabajos adelante, que por regla general será insuficiente, lo que llevará consigo nuevos retrasos y mermas en la calidad de los mismos, que darán lugar a nuevos flecos que quedarán pendientes, a sumar a muchos de los ya abiertos y a más trabajos nuevos que surjan. En resumidas cuentas un círculo vicioso de muy malas consecuencias.

No se suele prestar desgraciadamente demasiada atención a entregar productos lo más finos posibles, no digo que se entreguen perfectos, porque ni se va a conseguir y además va a obligar a un sobreesfuerzo que tampoco resulta rentable, pero sí que se dedique suficiente atención al proceso de análisis, al impacto que los requisitos funcionales puede tener sobre el producto (en el caso de mantenimientos) y detectar efectos colaterales de dicho desarrollo o dependencias respecto a lo que está hecho que se tienen que tener en cuenta en los nuevos desarrollos.

También es necesario probar adecuadamente lo que se entrega y no sólo a realizar escasas pruebas por encima. La entrega de un producto con problemas, como ya comenté en el párrafo anterior obliga a trabajar el doble, el triple o más y no sólo para el desarrollador, sino también para el cliente, el cual cada vez más disminuirá su nivel de tolerancia, porque generalmente si la interlocución con el cliente es un responsable técnico del proyecto, este será el que dé la cara directamente con los usuarios, los cuales no suelen tener o suelen caracterizarse por su paciencia y evidentemente por mucha capacidad de encaje que se tenga, sentirse como un saco de boxeo no es algo que se pueda aguantar mucho tiempo. A esto hay que sumar que en el cliente además del departamento de desarrollo, hay otros departamentos implicados, como por ejemplo, sistemas, calidad, explotación, etc… que también se ven afectados por estas circunstancias.

Lo peor de todo esto que la diferencia entre hacer las cosas mal o regular a hacerlas bien, no es tanta como se cree y en demasiadas ocasiones, por intentar ir por el camino más corto, no sólo se tarda más, sino que hace que el equipaje para el siguiente viaje sea más pesado, no solo para el desarrollador sino también para todos los que participan en el proyecto de desarrollo de software.

Ya he comentado en diversas ocasiones lo importante que resulta la comunicación para que un proyecto de desarrollo de software salga adelante. La falta de comunicación provoca malos entendidos y hace que se tengan que cubrir los huecos sin información por interpretaciones por parte de los desarrolladores o de los responsables del proyecto.

Estas interpretaciones, por mucha experiencia que se tenga y por la mejor voluntad que se ofrezca, suelen fallar en la mayoría de los casos, ya que los usuarios suelen pensar diferente y tener otro tipo de necesidades que las que imaginan los desarrolladores, que por regla general somos bastante creativos, estando esta creatividad en muchas ocasiones de espaldas a la realidad de lo que los usuarios necesitan.

La comunicación tiene que ser fluida entre gestores de proyecto, equipo de proyecto y usuarios y también entre cliente y proveedor. Hay que evitar en la medida de lo posible dar cosas por sabidas, salvo que sean obviedades, no hay que tener miedo a preguntar todas las veces que sea necesario si hay alguna duda o algo no se entiende, mejor preguntar, mejor parecer pesado que tomar caminos equivocados, ya que lo primero no cuesta dinero y lo segundo sí y en ocasiones mucho, tanto para el cliente como para el proveedor.

Informar es más fácil de lo que parece, poner una copia en un correo simplemente a efectos informativos, comentar un detalle que puede tener cierta importancia, reunirse de vez en cuando para ver cómo va todo, llamar por teléfono o escribir un correo cuando se tiene una duda, etc…

La información o comunicación entre los participantes en un proyecto de desarrollo de software no asegura que compile, sea fácil de mantener o que funcionalmente sea correcto, pero desde luego que incrementa las posibilidades de que lo que al final se obtenga se parezca a lo que se quiere y se reduzcan los malos entendidos, los cuales a su vez solo traen problemas.

Continuando con el estudio del grado de estabilidad (o inestabilidad) de un paquete en función de sus valores de acoplamiento y acoplamiento eferente, tal y como fueron enunciados por Robert Cecil Martin, toca establecer su relación con una de las características de la programación orientada a objetos como es la abstracción.

El mismo Robert Cecil Martin especificó que un paquete con una estabilidad máxima (o inestabilidad = 0) debería ser abstracto al máximo y que un paquete con estabilidad mínima tiene que ser concreto al máximo.

El razonamiento resulta lógico, ya que un paquete con inestabilidad 0 quiere decir que tiene no tiene acoplamiento eferente, es decir, no depende de ninguna clase de otro paquete y que como mucho tendrá valores de acoplamiento aferente o lo que es lo mismo hay clases de otro paquete que dependen de clases de este paquete, las cuales “fuerzan” a los desarrolladores a minimizar los cambios en el paquete por sus posibles consecuencias en dichas clases externas. ¿Cómo se consigue llevar la estabilidad a su máxima expresión? Pues forzando a que el mayor número de clases del paquete sean abstractas.

Recordemos que una clase abstracta es aquella que tiene al menos un método abstracto y que un método abstracto es aquel que solo presenta su especificación pero no su implementación. Una clase abstracta no puede ser instanciada y las clases que heredan de ella tienen que implementar los métodos abstractos definido en la superclase o volver a declararlos como abstractos, lo que daría lugar a que dicha subclase también sería abstracta.

El grado de abstracción de un paquete se define mediante la siguiente fórmula:

Abstracción = Clases Abstractas / (Clases Abstractas + Clases no Abstractas)

De esta manera, al igual que sucede con la inestabilidad, los valores de abstracción se encontrarán también en el rango de 0 a 1, de manera que tendremos el valor 1 cuando el paquete tenga todas las clases abstractas (o lo que es lo mismo no tenga clases no abstractas) y 0 cuando el paquete no tenga clases abstractas.

Robert Cecil Martin expone una relación interesante entre el grado de abstracción y el grado de estabilidad, pero como se puede apreciar ese grado se tiene que forzar, ya que ni la abstracción no la estabilidad son función del otro. Esto provoca que se puedan producir situaciones en cierto modo paradójicas como por ejemplo las siguientes:

– Inestabilidad = 1 y Abstracción = 1. Esto querría decir que nos encontramos con un paquete con clases de las cuales no depende ninguna clase de otro paquete y sin embargo todas las clases del paquete son abstractas y por tanto no instanciables. Esta situación es tan paradójica que será difícil de encontrar en un programa, ya que vendría a decir que no se estaría utilizando el paquete para nada.

– Inestabilidad = 0 y Abstracción = 0. En este caso nos encontramos con un paquete cuyas clases no dependen de ninguna clase de otro paquete y que además ninguna de sus clases es abstracta. Esta circunstancia es menos paradójica y por supuesto posible en un programa, vendría a hacer referencia a un paquete estable y concreto y por tanto rígido, siendo un paquete a vigilar si el acoplamiento aferente es alto, debido a que las posibilidades de efectos colaterales puede ser alta.

Tal y como enunció Robert Cecil Martin, los valores más deseables para cada paquete serían Inestabilidad = 1 y Abstracción = 0 e Inestabilidad = 0 y Abstracción = 1, no obstante, cualquier paquete que se encuentre en la recta que une ambos puntos se considera que tiene unos valores de estabilidad y abstracción compensados o equilibrados.

De lo anterior se puede deducir una nueva métrica que es la distancia de un paquete respecto a esa recta ideal, que se calcula mediante la siguiente fórmula:

D = ABS((Abstracción + Inestabilidad – 1) / SQRT(2))

devolviendo unos valores que se encontrarían en el rango entre 0 y 0’707, que indicarían que el paquete se encuentra sobre la recta o en el punto más extremo posible.

También hay cálculos de dicha distancia estableciendo el rango entre 0 y 1, aplicando la siguiente fórmula:

D = ABS(Abstracción + Inestabilidad – 1)

Por tanto, con lo estudiado en el anterior artículo y éste, basado en los enunciados de Robert Cecil Martin, es posible tener una serie de métricas que nos permitan servir de referencia a la hora de estudiar la calidad en el diseño de paquetes (y en general del diseño) de una determinada aplicación.

Otras métricas de calidad que resultan interesantes de estudiar están relacionadas con el cálculo de acoplamiento aferente (hacia dentro) y eferente (hacia afuera) de un paquete y la relación entre los mismos, dando lugar a una métrica resultado de ellas denominada inestabilidad de un paquete. Estas tres métricas fueron propuestas por Robert Cecil Martin aka “Uncle Bob” (más conocido posteriormente por liderar iniciativas orientadas a metodologías ágiles de desarrollo y programación extrema) en el año 1995.

Desde la perspectiva de un paquete concreto el acoplamiento aferente se produce cuando otro paquete hace uso de atributos y/o métodos de clases de dicho clase o hereda de alguna de ellas y el acoplamiento eferente se produce cuanto dicha clase hace uso de atributos y/o métodos de clases de otro paquete o hereda de clases de dicho paquete.

Por tanto el cálculo del acoplamiento aferente se obtiene mediante la suma de clases de otros paquetes que cumplen las características indicadas en el párrafo anterior y el acoplamiento eferente se obtiene como la suma de clases de otros paquetes de los cuales dependen clases del paquete con el que se está trabajando.

Como su propio nombre indica se trata de métricas de acoplamiento y como hemos estudiado previamente en las métricas de Chidamber y Kemerer, existe relación directa entre el acoplamiento, la complejidad, la mantenibilidad y la selección de clases (o paquetes) donde hay que prestar más atención a la hora de realizar las pruebas unitarias.

Un alto acoplamiento aferente hace referencia a un paquete con un alto grado de responsabilidad. La responsabilidad y la estabilidad son dos conceptos que suelen ir cogidos de la mano, precisamente porque al existir un elevado número de clases que dependen de clases del paquete, se tiene que ser necesariamente más prudente a la hora de realizar modificaciones en clases del paquete por los posibles efectos colaterales que se pueden producir. No obstante la estabilidad de un paquete no es función exclusivamente del acoplamiento aferente como veremos más adelante en la definición de inestabilidad.

Un alto acoplamiento eferente hace referencia a un paquete con un alto grado de dependencia. La dependencia y la inestabilidad son también dos conceptos íntimamente relacionados, ya que el funcionamiento de las clases del paquete dependen del comportamiento de clases externas, lo que las hace susceptibles de efectos colatarales en las modificaciones de las mismas y por tanto su funcionamiento entraña una mayor incertidumbre.

La inestabilidad de un paquete es la métrica que enfrenta entre sí al acoplamiento aferente y eferente a través de la siguiente fórmula:

Inestabilidad = Acoplamiento eferente / (Acoplamiento eferente + Acoplamiento aferente)

Por tanto los valores de inestabilidad se encontrarán dentro del rango de valores entre 0 y 1.

Estudiando los valores extremos podemos afirmar que si la inestabilidad de un paquete es 1 quiere decir que el acoplamiento aferente es 0 o lo que es lo mismo ninguna clase externa al paquete tiene una relación de dependencia respecto a una clase del paquete, por lo que el paquete sólo tiene dependencias hacia clases externas al paquete. El valor 1 indica una inestabilidad “extrema” del paquete (no obstante, habría que valorar también el valor individual del acoplamiento eferente, ya que, es una opinión personal mía, no todas las inestabilidad con valor 1 tendrían por qué ser iguales) ya que por un lado su comportamiento depende de clases externas, lo cual la hace posible víctima de efectos colaterales y por otro el hecho que no haya clases que dependan del paquete, da una mayor libertad a la hora de realizar modificaciones en el mismo ya que no hay que pensar en terceras clases a la hora de realizar modificaciones en el mismo (también habría que matizar esto, ya que puede haber dependencias entre clases del paquete, medibles mediantes distintas métricas, que provoquen que no sea tan ágil o sencillo modificar el paquete).

Si la inestabilidad es 0 quiere decir que el acoplamiento eferente es 0, lo que viene a decir que el paquete solo tiene responsabilidades y por tanto es menos proclive al cambio debido a que modificaciones en el mismo pueden tener repercusiones en clases externas.

Como la inestabilidad puede tomar cualquier valor entre 0 y 1, en función de a qué extremo se acerque más podemos darle una interpretación al resultado.

Existe un cierto tipo de usuarios que aparecen pocas veces al cabo del año pero que cuando lo hacen generan mucho ruido.

Aparecen con una incidencia o con una petición que es lo más urgente que existe, que no pueden trabajar si no se realiza esa tarea y que es posible que el mundo deje de girar si para antes de ayer no la tienen disponible.

Una vez generado el ruido y haber puesto sobre aviso a todas las personas que hayan podido, desaparecen. Trasladan la responsabilidad funcional de la tarea a otra persona (que lo mismo está puesta sobre aviso o no) y no quieren saber nada más de la tarea, solo que se ejecute y cuanto antes.

Generalmente estas incidencias o peticiones no son tan graves y su urgencia es el resultado de la falta de modulación de la misma por parte de estos usuarios, es decir, reciben una queja (que lo mismo es vehemente) y como no quieren que se les vuelva a molestar por lo mismo le dan una urgencia a la misma que no le corresponde y por supuesto eluden cualquier responsabilidad al respecto (lo mismo lo que “falla” no es software sino que la especificación que facilitó en su día no es la adecuada) porque lo suelen tener claro: se quejan del sistema de información, pues nada, que lo corrija el Departamento de Informática que para eso está (de hecho procurarán darle tus datos de contacto al que les remitió la queja para que se pongan en contacto contigo).

¿Qué se hace con este tipo de usuarios? Es complicado porque además suelen tener una posición en la organización superior a la que tienes tú. Mi recomendación es que hagas una evaluación de la petición o incidencia que ha realizado: complejidad de realización de la tarea, recursos disponibles y tu opinión sobre el grado de criticidad (es probable que tu conocimiento del sistema sea mayor que el suyo) poniéndote en contacto, si fuera necesario, con quien reportó la incidencia.

Una vez hecho eso se informa al usuario que te reportó la tarea (aunque sepas que no te vaya a echar cuenta, es importante que quede constancia de que le has avisado), a la persona o personas que designó y al peticionario original y se trata de consensuar cómo y cuándo se le va a dar respuesta a la misma (lo mismo no hay medios y hay que buscar financiación para los mismos). Generalmente se suele llegar a acuerdos ya que una vez puestos los pies en el suelo, lo que era tan urgente no lo suele ser tanto y se coge también conciencia de los recursos reales que están disponibles para la realización de esos trabajos.

El problema no es el ruido, no es que se quejen sino el hecho de que el producto solo exista cuando se les “molesta” a ellos (lo mismo, en medio de todo eso, han existido problemas más importantes en el sistema en los que ni siquiera ha intervenido porque no se ha llegado a enterar o más bien porque nadie les ha “molestado” con ellos) y esa existencia se limita al intervalo de tiempo que tardan en largar la responsabilidad a terceros (y a recordarte cada cierto tiempo (si vuelven a ser “molestados”) con el mismo ruido).

Ese dato es tremendamente relevante y toda una cura de humildad. Cada entrada en un blog es solo un pequeño granito de arena dentro del inmenso mundo de los contenidos en Internet, sólo habría que sumar el número de artículos escritos este mes en otros servicios de blog como Blogger, los contenidos de los periódicos digitales, las distintas páginas web empresariales y personales, todo lo que se publica en las redes sociales, Youtube, etc… como para darnos cuenta de que podemos sentirnos afortunados con cada persona que decide dedicar unos minutos de su atención a leer una de nuestras entradas.

Cada vez más personas deciden participar activamente en la red aportando sus contenidos y los que ya lo hacían cada vez ofrecen más y a través de más medios. Todo esto hace que conseguir captar la atención cada vez es mas difícil, ya que existen más medios diferentes donde poder consultar un determinado contenido los cuales a su vez tratan de mejorar la calidad de los mismos como vía para fidelizar y conseguir nueva atención. Como la audiencia tiende a dispersarse quien consigue captar y retener la atención tiene un auténtico cheque al portador, no ya por la capacidad de los ingresos directos o indirectos que se pueden obtener a través de tu sitio web, sino por la capacidad de haber conseguido algo tan complicado como atraer la audiencia.

Dada la manera en que concibo la web como medio de expresión y de libertad, noticias como la que ha anunciado WordPress me ponen bastante contento.