ITRP

Hola,
Para los que necesitéis trabajar con sistemas de ticketing en vuestros servicios de mantenimiento, más que recomendado, https://www.itrp.com.
Entre otros temas:
* Ofrecido como SaaS
* Integración con Team Foundation Server entre otros
* Seguimiento de SLAs
* Configuración de plantillas para diferentes tipos de ticket
* Asignación rápida de incidencias a problemas
* Multi-proveedor de servicios
* Plantillas para respuestas pre-configuradas, accesible de manera rápida para problemas activos
* Se licencia por usuario operador, no hay coste por usuario estándar (creador de tickets)
Un abrazo.
Miguel.

Buenas Prácticas: La Importancia de los Comentarios

Poner comentarios en un código siempre se ha considerado por la mayorí­a como una labor aburrida, tediosa, poco motivante en general.
Luego está el otro extremo, los que se dedican a poner parrafadas de libro en cada lí­nea o en la descripción de los métodos.
Como siempre, los extremos no suelen ser las mejores soluciones. Lo recomendable es siempre comentar, pero a ser posible sin redactar el quijote por cada método o trozo de código. Los comentarios pueden resultar básicos para entender qué está haciendo un determinado algoritmo.
Es algo bastante natural, sobre todo para los programadores con poca experiencia, el tener la creencia de que se van a acordar de lo que hací­a el algoritmo, por lo que bajo esa premisa el uso del comentario pierde sentido para ellos. A medida que la experiencia va llegando se llegan a nuevas conclusiones:
1) Como me he encontrado código que no he hecho yo y no está comentado no tengo ni idea de lo que hace. Además, el compañero que lo ha hecho o está a tope y no me lo puede contar o justamente se ha ido una semana de vacaciones. Mira tíº por donde esto tiene que estar arreglado esta misma mañana por lo que me voy a tener que quedar comiendo delante del ordenador, así­ que, la próxima vez que programe algo que no es para mi, lo comentaré, y le diré a mi compañero que haga lo mismo.
2) Estoy solventando una incidencia y recuerdo perfectamente que el código lo hice yo, pero miro y remiro lo que hace y no me acuerdo para nada de por qué tomé esta solución. Es más, no sé ni qué hace o para que sirve esto. Será mejor que comentemos los métodos al crearlos, incluidos los parámetros que se la pasan, así­ nos evitaremos estos problemas.
3) Mira qué bien, el método está comentado, sé lo que hace por lo que voy a arreglar la incidencia en un momento. El problema viene cuando resulta que alguien cambió el comportamiento del método y no actualizó el comentario, entonces me estoy creyendo que hace lo que dice el comentario… ¿os imagináis el resultado, no? … Está bien, además de añadir un comentario al crear el método, cuando lo modifique también lo ajustaré.
Por ejemplo, trabajando con C# el añadir comentarios a método es muy cómodo, íºnicamente pulsad tres veces “/” justo en la linea de encima de la definición del método y os aparecerá la estructura xml que tenéis en el método de abajo (sin rellenar claro, la tendréis que rellenar vosotros).
/// <summary>
/// Inserta un nuevo coche
/// </summary>
/// <param name=”codigoCoche”>Identifica de forma íºnica el coche</param>
/// <param name=”nombreCoche”>nombre del coche</param>
/// <param name=”numeroPuertas”>níºmero de puertas del coche</param>
/// <param name=”codigoMarca”>identifica de forma íºnica la marca del coche</param>
public void Insert(int codigoCoche, string nombreCoche, int numeroPuertas, int codigoMarca)
{
 // código necesario para la inserción
}
La buení­sima noticia al respecto es que ahora cuando utilicéis el Intellisense de Visual Studio, al seleccionar el método os aparecerán los comentarios que habéis puesto, algo que aumentará vuestra productividad.
Para llevar a cabo la misma acción con VB.NET en lugar de usar “/” tenéis que usar “‘” (comilla simple).
Otra buení­sima noticia es que existen herramientas que a partir de los comentarios que añadais a vuestros métodos, clases, interfaces, propiedades generan documentación automáticamente. Los famosos JavaDoc en java son un ejemplo, los archivos .chm para .NET lo mismo.
Saludos.
Miguel.

Reutilización y Mantenibilidad en HTML

Nos cansamos de hablar de la mantenibilidad del código, de paquetizar, de reutilizar, de estándares de nomenclatura, de estilos definidos de programación, de separar entre el Modelo la Vista y el Controlador, de separar las aplicaciones en capas…
Pero no hay manera de que se nos meta en la cabeza que a la hora de maquetar una aplicación web tí­pica, en la que existen millones de formularios de entrada (formularios que en una aplicación de escritorio se llevan a cabo arrastrando, soltando y colocando con el ratón elementos en el formulario), se haga siguiendo también un patrón, se aplique la reutilización y se defina una estructura que esté preparada para el cambio en caso de necesitar modificar el diseño por cambios en los requerimientos.
¿Consecuencias? Cada jsp, asp, aspx, php o html son de su padre y de su madre. Algunos resuelven problemas por javascript, otros con posts, otros con request, unos maquetan con tablas, otros con capas, otros <br> y &nbsp… Otros usando class, otros con style a pelo o asignando valores a las propiedades de los controles HTML.
¿Y con el tiempo que supone hacer todo eso… por qué no somos capaces de metérnos en la cabeza de la necesidad imperiosa de definir también una forma de trabajar con HTML?
Un saludo.
Miguel.

Reparabilidad

Me hace mucha gracia lo de aplicar el término de “Reparabilidad” al ámbito de software. Cuando pienso en reparar me vienen otras cosas antes a la cabeza, como el coche, la lavadora o un enchufe.
Pero lo cierto es que el í­ndice de reparabilidad de un software afecta directamente a la mantenibilidad del mismo, por lo que si somos conscientes de ello tal vez empecemos a enfocar el problema de la mantenibilidad con algunos argumentos más en el bolsillo.
Ahí­ os va una definición de Reparabilidad:
“Podemos decir que un software es reparable si permite la corrección de sus defectos con una cantidad de trabajo limitada y razonable”. (Referencia: Mantenimiento de Software. Modelos técnicas y métodos para la gestión del cambio. Editorial Ra-Ma)
Por poner un ejemplo de reparabilidad en otros ámbitos, por ejemplo, en el del automóvil, resulta totalmente crí­tico. Por ejemplo, al diseñar un coche se tiene en cuenta cuáles son las piezas que más pueden fallar y desgastarse, y se condiciona el diseño para que dichas piezas sean lo más facilmente sustituibles.
Un software por mucho que se use no se gasta. Ya le podemos dar veces al botón de aceptar, que, en principio, no deberí­a desgastarse y dejar de funcionar sin motivo aparente.
Otro de los condicionantes que afectan a la reparabilidad es el tamaño y el níºmero de las piezas. Esto si es algo que nos afecta en el desarrollo de software. Si el tamaño o el níºmero de nuestros módulos es muy grande esto puede afectar a la reparabilidad. Aunque para mi más que el tamaño o el níºmero de módulos tal vez sea el níºmero de interacciones que exista entre los mismos, cuantas menos dependencias tengan entre ellos y cuanto más hagan lo que tengan que hacer, pues mejor (tal vez os suena más si esto íºltimo lo expreso como “alta cohesión y bajo acoplamiento”).
Para finalizar, por supuesto, la documentación. Prueba tíº a desmontar el motor del coche sin haberte leí­do el manual correspondiente.
Saludos.
Miguel.

Buenas Prácticas: Encapsular, encapsular y encapsular.

Quisiera poner un ejemplo bastante gráfico para dejar patente la importancia de la encapsulación. Es muy bonito el concepto de encapsulación, todos lo conocemos y lo utilizamos, pero seguramente no todas las veces que deberí­amos. Inicio el ejemplo:
Tenemos un objeto que controla cual es el tabulador activo en una tí­pica ventana con pestañas, como esta. Hemos encapsulado nuestro objeto y le hemos creado un método píºblico que se encarga que desde fuera del objeto poder elegir cual es la pestaña activa.
Algo así­ como: (código C#)
ObjetoTabulador tab = new ObjetoTabulador();
tab.SetPestaña(3); // 3 es el níºmero de la pestaña que vamos a activar
Vale, está claro que esto funciona, pero no está bien encapsulado. Diseñando este objeto así­ estamos dando por hecho que sabemos lo que hace por dentro el ObjetoTabulador. Si yo quiero activar la tercera pestaña le paso un 3 y ese es el dato que se utiliza internamente.
¿No creéis que serí­a mejor solución la siguiente?
ObjetoTabulador tab = new ObjetoTabulador();
tab.SetPestaña(ObjetoTabulador.Pestañas.Informes); // informes corresponde a la pestaña de informes en el tabulador de la imagen
¿Qué ha cambiado aquí­? Pues que en lugar de pasarle el níºmero le estamos pasando un tipo enumerado que aporta el mismo ObjetoTabulador y es el que internamente va a tratar cual es la pestaña a activar. ¿Quién dice que mañana la pestaña de Informes va a seguir en la tercera posición? Si esto cambiara todas las llamadas que activan el tabulador por níºmero pasarí­an a ser inconsistentes, mientras que pasándole el tipo enumerado seguirí­a activándose la pestaña que le habí­amos indicado. Por cierto, pasándole un í­ndice estamos dejando al descubierto que internamente estamos gestionando las pestañas con una lista.
Este error viene dado muchas veces porque cuando estamos tratando con objetos que nosotros mismos creamos y a los cuales tenemos acceso directo a partir de nuestra propia aplicación nos acostumbramos a que sabemos lo que hacen internamente y lo podemos cambiar. No resulta esta la mejor manera de programar, a la hora de desarrollar hay que pensar siempre en que los componentes que hacemos han de poder funcionar de forma totalmente independiente y que no debemos necesitar mirar su código interno para saber qué es lo que hacen.
Si con un objeto tan tonto como un control de tabulación la mejora es tan grande, (recuerdo que hemos evitado los errores que se generarí­an al modificar el orden de las pestañas, hemos elevado la mantenibilidad del código y la productividad del desarrollo), doy por hecho que os hacéis a la idea de lo que supondrí­a tener en cuenta estas cosas al trabajar con objetos más complicados.
Es curioso porque cuando desarrollamos DLL’s de componentes o de objetos el concepto de encapsulación lo tenemos más claro, pero cuando utilizamos objetos propios de los cuales tenemos acceso al código fuente, se nos olvida lo de la encapsulación.
No hay que dar por hecho que para entender lo que hace una clase hay que mirar su código.
Saludos.
Miguel.

Buenas Prácticas: Legibilidad y Mantenibilidad del Código

Y es que muchas veces nos olvidamos de que nuestro código va a tener que ser interpretado, leí­do y mantenido por otras personas, o incluso por nosotros mismos en un futuro.
Mantener estructuras similares a la hora de programar, un estilo de programación, un orden determinado y un código claro, harán que la mantenibilidad de nuestras aplicaciones se dispare. Este aspecto se ve aíºn más potenciado en grupos de trabajo de alta volatilidad, donde la estabilidad del níºmero de profesionales que forman el grupo es alta. Me refiero tanto a la baja de miembros del equipo como a la rápida incorporación de nuevos profesionales para aumentar el tamaño del grupo.
Quisiera dejar patente la diferencia de legibilidad y mantenibilidad entre dos fragmentos de código que llevan a cabo exactamente la misma funcionalidad
Ejemplo de baja legibilidad y mantenibilidad (código C#):
public bool NumPuerMayorQue(int t)
{
    int n = 0;
    coche[] lista = DameListaCoches();
    for(int i=0;i<lista.lenght;i++)
        n = n + (coche)lista[i].NumPuertas;
    if (n>t)
        return true;
    else
        return false;
}
Ejemplo de mejor legibilidad y mantenibilidad
/// <summary>
/// Añade un nuevo parámetro a la lista
/// </summary>
/// <param name=”numPuertas”>Níºmero de puertas a comparar</param>
/// <param name=”lista”>Lista genérica de coches sobre la que hacer el cálculo</param>
/// <returns>Retorna verdadero en el caso de que la variable numPuertas pasada por parámetro sea mayor que el resultado de sumar todas las puertas de los coches pasados por parámetro en la variable lista. Retorna falso en caso contrario, es decir cuando es menor o igual.</returns>
public bool IsNumeroPuertasMayorQue(int numPuertas, List<coche> lista)
{
    int total = 0;
    foreach (coche unCoche in lista)
    {
        total += unCoche.NumPuertas;
    }
    return (total > numPuertas);
}
Aspectos que hacen notar la mejora de la mantenibilidad y la legibilidad de ambas funciones
1) Se dispone de un comentario sobre qué labor va a realizar la función, qué papel juega cada uno de sus parámetros y qué valores se esperan retornar y en qué condiciones.
2) El nombre de la función, al marcar el prefijo “Is” ya nos da la pista de que va a devolvernos un booleano. IsNumeroPuertasMayorQue da más pistas al desarrollador que NumPuerMayorQue.
3) La lista de coches es pasada por parámetro a la función, siendo además una lista genérica. Sabemos exactamente de dónde nos llega la lista.
4) Uso de foreach en lugar de for. Usando foreach aumentamos la legibilidad y la elegancia de nuestro código.
5) Uso de lista genérica en lugar de arrays. Nos estamos evitando hacer el cast “(coche)lista[i]”, que además no nos asegura que lo que realmente tenga la lista sean objetos de tipo coche, puede darse un error de casting.
6) El nombre de las variables utilizadas es mucho más descriptivo.
7) Llaves en sentencias de una sóla lí­nea. Realmente funcionan igual, pero si a las sentencias for, foreach, if y else le añadimos llaves de apertura y cierre aunque incluyan una íºnica sentencia, lo leeremos mejor.
8) Creo que queda bastante claro que se lee mejor “return (total > numPuertas)”
9) Una linea en blanco entre bloques. ¿La vista lo agradece, no?
Saludos.
Miguel.

Resolución de Errores de Software.

De todos es sabido que los errores en el software son el pan nuestro de cada dí­a. Alguna de las aplicaciones con las que nos toca trabajar dan más problemas que otras, y lo más normal es que si una aplicación se mantiene viva, con constantes actualizaciones y mejoras, los problemas vayan surgiendo a medida que se añaden nuevas funcionalidades. Por no hablar por supuesto de nuevas aplicaciones, recien salidas del horno, en las que tras una arquitectura moderna y robusta, puede esconderse una falta de testeo de algunos módulos o funcionalidades, o simplemente algunos descuidos de programación que aíºn no ha degenerado en error ya que para explotar necesitan verse inmersas bajo una serie de condicionantes que en entornos de desarrollo es difí­cil simular.
Y estoy hablando de errores, de errores de programación, tí­picos mensajes de alerta, con nuesto querido sí­mbolo de admiración, o su triangulito… no de errores provenientes de una mala toma de requerimientos (modulos que no fallan pero no hacen lo que se supone que tení­an que hacer). Petadas, reventadas, bugs… ya sabéis de lo que hablo.
Sobre prevención de errores hablaremos otro dí­a, pero… ¿cómo resolvemos los errores de software una vez se han producido?
Si tenemos suerte y nuestro Proyecto cuenta con un Plan de Riesgos en el cual se ha contemplado el riesgo de errores en el software y se ha documentado cuales son los pasos que debemos seguir en caso de que se produzca un error… tendremos bastante ganado. Vamos a suponer que no es así­, para hacer el “más difí­cil todaví­a”.
La posibilidad de resolver un error comienza cuando este se produce (obvio), lo que no es tan obvio es que debemos disponer de medios para detectar el error lo antes posible, cosa de la que a veces nos olvidamos. “Bueno, si falla ya llamarán”. “No ha llamado nadie en toda la mañana, eso es que va bien”. ¿Por qué debemos esperar a la llamada de un usuario para ponernos en marcha? ¿No serí­a mucho mejor que una vez se ha producido un error, la propia aplicación sea capaz de enviarnos una alarma al equipo de trabajo, y así­ poder ponernos a investigar prácticamente en el acto? Que bonito serí­a que antes de que llamara el usuario llamarle tíº. Hola buenas tardes señor Fulanito, hemos observado que ha surgido un error en la Aplicación durante el proceso de blablabla, le informamos que tenemos el error controlado, que no ha afectado a la transacción que estaba llevando a cabo, y que tenemos ya a una persona resolviendo la incidencia. O… que te llamara el usuario… Ah si, buenas tardes sr Menganito, somos conocedores del error que se le ha producido en la aplicación, se ha realizado un análisis del mismo, y visto que su nivel de importancia es medio, y no produce ningíºn bloqueo en la aplicación, hemos postpuesto la publicación del parche a la primera hora de mañana, para así­ juntarlo con otras mejoras que tení­amos pendientes.
Qué diferencia eh. Y no es tan difí­cil conseguir que una aplicación mande un SMS o un E-Mail cuando se ha producido una excepción en la aplicación.
Y para finalizar unas cuantas frases.
“Los errores de software desprestigian a la empresa, desprestigian al producto, desprestigian al grupo de trabajo y desprestigian al programador. Además, cabrean.”
“La confianza del usuario en un producto es inversamente proporcional al níºmero de errores generados por la aplicación, multiplicado por la importancia de los mismos (y añadirí­a también por aquí­ algo sobre la media de la distancia de tiempo entre errores)”.
“Esta claro que no se puede tratar igual la gestión de errores de sistemas crí­ticos como el de una central nuclear o un cohete espacial, pero eso no quiere decir que nos tengamos que olvidar de la gestión de errores de un simple editor de texto. Siempre que lo queramos vender, claro.”
Seguimos en la siguiente parte.
Saludos.
Miguel.