ClasesAvanzadas v1.0.0.0

Fruto del anterior post sobre buenas prácticas, se me ha ocurrido la idea de ir añadiendo las clases que os vaya comentando en una dll, para que así­ podáis probar su funcionamiento y aprovecharlas para vuestros desarrollos. La dll está realizada en C# y podréis referenciarlas en vuestros proyectos con la plataforma .NET
En la primera release incluyo la clase Redireccion, que os ayudará a hacer más legibles y mantenibles vuestros response.redirect.
ClasesAvanzadas.dll v1.0.0.0
Se aceptan comentarios, mejoras, errores…
Saludos.
Miguel

Buenas Prácticas: Encapsular Construcciones Complejas

Supongo que estaréis acostumbrados a ver cosas como estas (código C#)
Response.Redirect(“~/home/pepito.aspx?idarticulo=” + idarticulo.toString() + “&idusuario=” + idusuario.toString() + “&idcategoria=” + idcategoria.toString() + “&activo=” + activo);
En el caso del ejemplo tenemos la instrucción response.redirect, la cual muchos de vosotros conoceréis, y que se encarga de redireccionar a nuestro navegador a la url que se le pasa por parámetro. Muchas veces vamos a necesitar pasar valores en la URL para que sean recogidas en la página de destino, y “no nos queda más remedio” que hacerlo de esta manera.
La verdad es que para redirecciones con urls sencillas aíºn es tratable, pero como tengamos que empezar a concatenar parámetros y más parámetros, te puedes volver loco. Por ello, una buena práctica resulta el encapsular todos estos oomportamientos para ayudar en la lectura del código y el posterior mantenimiento de la aplicación.
Os dejo aquí­ el comportamiento de hipotética clase que encapsula esta buena práctica, a ver si qué os parece (código C#)
Redireccion miURL = new Redireccion(“~/home/pepito.aspx”);
miURL.AddParameter(“idarticulo”, idarticulo);
miURL.AddParameter(“idusuario”, idusuario);
miURL.AddParameter(“idcategoria”, idcategoria);
miURL.AddParameter(“activo”, activo);
miURL.Ir();
¿Cómo lo leéis mejor? ¿Os hacéis una idea de lo que hace por dentro la clase, no?
AddParameter es un método sobrecargado donde el primer parámetro es el nombre y el segundo el valor. Podemos pasarle como valor diferentes tipos de datos, ya que está sobrecargado con el tratamiento para cada uno de ellos.
El constructor acepta un parámetro de entrada que es la base de la url a la que vamos a llamar, aunque podrí­amos instanciar la clase sin pasarle ningíºn parámetro, y luego usar la propiedad miURL.URLBase para definirla.
Por supuesto, y siguiendo las buenas prácticas, la clase Redirección deberí­a encapsular también sus excepciones propias que lanzarí­a en los casos necesarios y que podrí­an capturarse desde fuera. Por ejemplo, ¿y si instanciamos la clase sin pasarle la URL base y tampoco la añadimos usando la propiedad? Al lanzar el método Ir() deberí­a saltar una “NoHayURLBaseDefinidaException”, ¿no creéis?
Otro consejo para rematar, serí­a sobreescribir el método toString() de la clase, para que devolviera la URL generada hasta el momento, y así­ poder hacer cosas del tipo:
MostrarMensaje(“Esta es la URL Generada: “+  miURL);
Esta forma de encapsular las construcciones complejas es aplicable a otros campos, como por ejemplo para generar una secuencia SQL. Otro dí­a os dejo un ejemplo.
Saludos.
Miguel.

Buenas Prácticas: Definición de Excepciones Propias

Inicio una nueva saga de opinión relacionado con las buenas prácticas. La primera, está relacionada con la programación, en concreto con la creación de excepciones propias, relacionadas con las clases que vayamos generando.
Para los que no conozcan o no hayan trabajado con excepciones, me ahorro la definición y me uno a la reutilización de código: https://es.wikipedia.org/wiki/Manejo_de_excepciones
Una vez situados en el contexto, paso a describir la práctica con un ejemplo.
Supongamos que utilizamos una clase que nos ayudará a extraer datos de un dispositivo GPS, que en un alarde originalidad vamos a llamar “GPS”. La clase tiene varios métodos y no tenemos acceso al código, ya que la importamos a traves de una dll.
1) CountSatelitesDisponibles(): Retorna el total de satélites disponibles para el dispositivo GPS
2) GetLongitud(): Retorna la longitud actual
3) GetLatitud(): Retorna la latitud actual
4) Conectar(): Conecta el dispositivo GPS
5) Desconectar(): Desconecta el dispositivo GPS
6) IsConexion(): Retorna verdadero si hay conexión con el gps, retorna falso en caso contrario
Si nos pusiéramos en marcha para utilizar la clase en nuestra aplicación, podrí­amos crear algo similar a esto (uso sintaxis C#)
public void miMetodo()
{
    try
    {
        GPS objeto = new GPS();
        objeto.Conectar();
        if (objeto.IsConexion())
        {
            if (objeto.countSatelitesDisponibles()>=4)
            {
                // mostrarPorPantalla es un
                // método que genera una pantalla
                // emergente
                mostrarPorPantalla(objeto.GetLongitud());
            }
        }
    }
    catch(Exception ex)
    {
        // tratarExcepcion es un método
       // que se encarga de mostrar el
       // mensaje por pantalla.
        tratarExcepcion(ex);
    }
    finally
    {
        objeto.Desconectar();
    }
}
¿Qué ocurrirí­a si se produce alguna excepción en la ejecución del código? Pues se harí­a el catch con el objeto Exception, y tratarExcepcion se encargarí­a de mostrar un mensaje por pantalla. Si hemos tenido suerte que en la definición de la clase GPS el desarrollador incluyó una excepción genérica con un mensaje de texto, con suerte almenos en ex.Message tendremos parte de la descripción del error. Es todo lo que podrí­amos hacer desde la llamada a la clase GPS con las herramientas que nos brinda. No somos capaces de tratar la excepción en la conexión, o en el recuento de satélites desde nuestro código, ya que no sabemos cíºando se produjo el error allí­ (si hay mensaje podrí­amos mirar el mensaje… pero eso es una cutrez nada recomendada y menos en este artí­culo)
A continuación dejo aquí­ lo que serí­a la definición del método Conectar de la clase GPS lanzando excepciones genéricas
public void Conectar()
{
    try
    {
        // Código encargado de conectar el dispositivo GPS
    }
    catch(Exception ex)
    {
        throw new Exception(“Error al conectar”);
    }
}
¿Y si en lugar de utilizar excepciones genéricas dejáramos definidas excepciones propias de la clase y las lanzáramos a estas en lugar de usar la excepción genérica?
public void Conectar()
{
    try
    {
        // Código encargado de conectar el dispositivo GPS
    }
    catch(Exception ex)
    {
        throw new NoSeHaPodidoConectarConElGPSException();
    }
}
public class NoSeHaPodidoConectarConElGPSException:Exception
{
    public NoSeHaPodidoConectarConElGPSException() : base(“Error Conectando”) { }
}
Esto ya es otra cosa, ya que ahora, desde nuestra aplicación podremos tratar exáctamente cual ha sido la excepción que se ha producido. Fijaros:
public void miMetodo()
{
    try
    {
        GPS objeto = new GPS();
        objeto.Conectar();
        if (objeto.IsConexion())
        {
            if (objeto.countSatelitesDisponibles()>=4)
            {
                // mostrarPorPantalla
                // es un método que genera
                // una pantalla emergente
                mostrarPorPantalla(objeto.GetLongitud());
            }
        }
    }
    catch(GPS.NoSeHaPodidoConectarConElGPSException ex)
    {
        //mandarEmailServicioTecnicoGPS se 
        //encarga de coger la excepción,
        // generar un email con la información
        // que incluye y mandarlo al técnico
       // con menor carga de trabajo de nuestra
       // organización.
        mandarEmailServicioTecnicoGPS(ex);
    }
    catch(Exception ex)
    {
        // tratarExcepcion es un método que
        // se encarga de mostrar el mensaje
        // por pantalla.
        tratarExcepcion(ex);
    }
    finally
    {
        objeto.Desconectar();
    }
}
¿Mucho mejor no? ¿Merece o no merece la pena el definir excepciones propias?
Saludos.
Miguel.