06.13.09

Return String vs Return Enum

Posted in Buenas Prácticas at 9:31 pm by Miguel

Qué bonito y al mismo tiempo qué sencillo, bonito y barato.

function string GetTipoMarca(int idMarca)
{
// acciones pertinentes para retorna el tipo de marca
// relacionado al id pasado por parámetro, los tipos se devuelven como
// strings “Mercedes”, “Seat”, “BMW”
}

vs

function TipoMarcaEnum GetTipoMarca(int idMarca)
{
// acciones pertinentes para retorna el tipo de marca
// relacionado al id pasado por parámetro, los tipos se devuelven como
// un tipo enumerado que tipifica los valores “Mercedes”, “Seat”, “BMW”
}

Es un pequeño detalle, pero mejoramos así la encapsulación, la abstracción, el mantenimiento, el coste del cambio… ¿Tanto esfuerzo cuesta entonces no olvidarse de estos detalles cuando se está construyendo?

Saludos.

Miguel.

Rating 2.00 out of 5
[?]

09.09.08

Ejemplos Prácticos del uso del Principio de KISS

Posted in Arquitectura, Buenas Prácticas, Web at 11:03 pm by Miguel

En posts anteriores hablamos ya alguna vez del Principio de KISS. Hoy toca un ejemplo práctico. Últimamente no paro de cruzarme con situaciones en las que el principio resulta una premisa básica. Para qué complicarse cuando hay soluciones sencillas y facilmente mantenibles que cumplen el requerimiento funcional suficientemente y hacen que el cliente obtenga su objetivo.

Como ejemplo, un botón, no sé si disponéis de una cuenta de Gmail, si es así, podréis comprobar que en las opciones de un e-mail tenéis la de imprimirlo. Hay miles de formas diferentes de provocar una impresión desde web, y la que ha elegido Google es la siguiente:

1) Al pulsar sobre el botón de imprimir se abre una ventana emergente y se carga el texto relacionado al e-mail más información básica de las direcciones implicadas, además aparece también en la parte superior el logo de Gmail

2) A continuación, tras la carga, se lanza una sentencia javascript que provoca que en el cliente se lance el cuadro de diálogo de selección de impresora.

3) El cliente selecciona la impresora y se imprime el contenido actual.

Ala fin. Así de simple. Si quieres imprimir un e-mail, lo imprimes sin problemas, que ese era tu objetivo.

¿Para qué complicarse más?

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

08.28.08

Buenas Prácticas: Uso de constantes para URL’s

Posted in Buenas Prácticas at 11:33 am by Miguel

Tras la vuelta de vacaciones el volumen de trabajo no me deja dedicarle mucho tiempo al blog, pero a pesar de eso voy a intentar incorporar aunque sea pequeños artículos que le sigan dando la vida suficiente.

Para hoy un pequeño truco que actúa como buena práctica en proyectos de tipo web ASP.NET (y otras tecnologías web).

Es muy común que a la hora de viajar entre páginas de un mismo proyecto, se utilice la instrucción correspondiente de redirección poniendo directamente la URL de la página. Algo así como (código C#):

response.redirect(“~/mantenimiento/coche.aspx”);

Esto en principio no tiene mayor problema, pero, podemos añadirle una cierta y sutil mejora:

response.redirect(ConstantesURL.MANTENIMIENTO_COCHE);

Siendo “ConstantesURL” una clase que contiene las constantes que almacenan las URL de las diferentes páginas que componen la aplicación.

Esto puede parecer una tontería, pero nos protege de forma muy sencilla de los posibles cambios de rutas de páginas que pueden sucederse a lo largo de la vida del proyecto. Es muy común que ante una mala definición inicial, o de un crecimiento inesperado del volumen de páginas, se tenga que restructurar la organización de carpetas. Mediante este método, el coste es muy similar al de hacer un refactoring de un paquete, evitando así los típicos problemas de ir revisando uno a uno todos los enlaces y corrigiendo el viejo enlace por la nueva ubicación.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

04.07.08

Buenas Prácticas: La Importancia de los Comentarios

Posted in .NET, Buenas Prácticas, Gestión del Mantenimiento, Java, Programación at 8:00 am by Miguel

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.

Rating 3.00 out of 5
[?]

04.06.08

Buenas Prácticas: Uso de Regiones

Posted in .NET, Buenas Prácticas, Programación at 7:35 pm by Miguel

Las regiones son otra herramienta que provee Visual Studio que ayuda a mantener el órden del código, aumentando así su mantenibilidad. Su principal característica es que según pulsas sobre la región esta se muestra o se oculta. Os describo por ejemplo las típicas regiones a usar en una clase.

public class Coche
{

#region Constantes

// codigo que define las constantes #endregion

#region Campos

// codigo que define los campos

#endregion

#region Propiedades

// codigo que define las propiedades

#endregion

#region Constructores

// codigo que define los constructores

#endregion

#region Métodos Públicos

// codigo que define los métodos públicos

#endregion

#region Métodos Protected

// codigo que define los métodos protected

#endregion

#region Métodos Private

// codigo que define los métodos private

#endregion

}

Si tenéis todas las clases estructuradas de la misma manera, encontraréis muy rápido las cosas. Además de que por supuesto la sensación de orden, el trabajar ordenado en sí, es un valor muy importante y que aumentará la mantenibilidad.

Un saludo.

Miguel.

Rating 3.00 out of 5
[?]

03.27.08

Definiendo Métodos Obsoletos (Deprecated)

Posted in .NET, Buenas Prácticas, Programación at 7:58 pm by Miguel

Para los programadores que trabajáis bajo el soporte de un framework o de un conjunto de librerías de terceros os habréis encontrado en alguna ocasión que a la hora de utilizar alguno de los métodos que os brinda el conjunto de clases, alguno de ellos os lo indica como “Obsoleto” o “Deprecated”.

Los métodos obsoletos son aquellos que han caido en deshuso y que el responsable de desarrollo del framework quiere, por algún motivo (reubicación del método en otra clase, cambio del nombre del método, cambio de los parámetros, nuevos métodos más eficientes…), eliminar en futuras versiones. 

Normalmente un proveedor que pasa a indicar sus métodos como obsoletos lo suele hacer de alguna o varias de las siguientes formas:

1) Incorpora una descripción en la documentación indicando que el método está obsoleto y que en futuras versiones será eliminado.

2) A la hora de compilar la aplicación aparece una alerta (warning) indicando que el método está obsoleto. Nos avisa el compilador pero la aplicación sigue compilando.

3) Al utilizar el método obsoleto la aplicación directamente no compila.

Tras la teoría, unos ejemplos de cómo declarar métodos obsoletos con C#

Primero, cómo declarar una clase como obsoleta, dando warning recomendando usar otra clase en lugar de esta

[System.Obsolete("usar clase ClaseNueva")]
class ClaseAntigua
{
    public void Metodo() { }
}

Segundo, cómo declarar en la nueva clase un método obsoleto, dando error de compilación si se usa un método en concreto y recomendando el uso de un método alternativo

class ClaseNueva
{
    [System.Obsolete("usar MetodoNuevo", true)]
    public void MetodoViejo()  { }
    public void MetodoNuevo()  { }
}

Tercero, un ejemplo de uso de las clases

// Genera dos alertas
// (una por la instancia a la clase y otra por la llamada al constructor)
ClaseAntigua antigua = new ClaseAntigua();

// No genera ni errores ni alertas
ClaseNueva nueva = new ClaseNueva();
nueva.MetodoNuevo();

// Genera un error, terminando la compilación
nueva.MetodoViejo();

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

02.14.08

Buenas Prácticas: El Arte del Debug

Posted in Buenas Prácticas, Programación at 8:12 pm by Miguel

Por temas laborales últimamente estoy teniendo contacto con proyectos donde participan un alto número de programadores con poquita experiencia o chicos y chicas con una beca y que dan sus primeros pasos en este mundo recién acabada la carrera o con alguna asignatura aún pendiente.

La verdad es que aunque parezca contradictorio estoy aprendiendo muchísimo de ellos, una cosa es que tengan poquita experiencia laboral y otra que no sepan de qué va esto y qué es lo que quieren. Está siendo una experiencia realmente gratificante.

Tras la puesta en situación me pongo ya con el tema principal del post que es sobre el debug. La verdad es que una de las cosas que estoy viendo al respecto de este perfil de profesional que antes comentaba, es que salen de sus carreras, modulos o estudios varios correspondientes sin que nadie les haya contado lo que es un debug, cosa que, sinceramente, no es que me sorprenda, es que me tiene realmente abrumado.

Por dios, no sabéis las horas y horas de resolución de errores, desesperos y cabreos que os váis evitar si ponéis en vuestra vida el  modeo debug de la aplicación que estáis desarrollando. Cualquier entorno de desarrollo medianamente decente, un Eclipse, NetBeans, Visual Studio, Delphi 2006, Zend Studio para PHP, incorpora dicho valor.

No lo dejéis de lado. Vuestra eficiencia se verá directamente afectada si no aprovecháis el recurso del debug.

Un saludo.

Miguel.

Rating 3.00 out of 5
[?]

01.30.08

Buenas Prácticas: Uso de StringBuilder en lugar de concatenación

Posted in .NET, Buenas Prácticas, Programación at 8:42 pm by Miguel

Hola a todos. 

Para los que no lo conozcáis, StringBuilder es una de las clases provistas por los framework de .NET y de Java. La finalidad de dicha clase es la de proveernos de una serie de herramientas que nos faciliten la concatenación de strings, ya no sólo en la mantenibilidad del código si no que también en cuanto a la eficiencia en rendimiento.

El uso es muy simple (código C#):

StringBuilder builder = new StringBuilder();

builder.Append(“hola”);
builder.Append(“qué”);
builder.Append(“tal”);
builder.Append(“estás”);

En lugar de:

String builder = String.Empty;

builder += “hola”;
builder += “qué”;
builder += “tal”;
builder += “estás”;

Además, disponemos de una serie de métodos más que nos facilitan un poco la vida, pero insisto que el valor más importante es el de la mejora de rendimiento.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.20.07

Buenas Prácticas: Los servicios web no deberían devolver tipos específicos de la tecnología

Posted in .NET, Arquitectura, Buenas Prácticas, Java, Programación, Servicios Web, Web at 11:32 pm by Miguel

Típico ejemplo de esta situación es un servicio web hecho en .NET que devuelve un Dataset.

Si se nos garantiza que el consumidor del servicio va a ser siempre un cliente .NET aún la cosa se sostiene un poco. El problema es si por ejemplo intentamos consumir un servicio que da un Dataset por otra tecnología que no es .NET.

Para los que tengáis experiencia trabajando con servicios sabréis que una vez que creas un servicio que devuelve un objeto o tiene por parámetro un objeto definido en el servicio, desde el cliente que consume el servicio tenemos visibilidad sobre la definición de dicho objeto. Si yo tengo un servicio que recibe por parámetro un objeto coche, yo desde el cliente puedo rellenar dicho objeto coche y pasárselo por parámetro al servicio. Lo mismo ocurre si el coche me lo devuelve el servicio, yo puedo conocer sus propiedades y extraer los valores de las mismas.

¿Pero qué ocurre con un dataset? ¿Ocurre lo mismo? Pues no.

El principal problema de un Dataset es que en tiempo de diseño no conocemos cuál es su contenido. Sólo lo sabemos en tiempo de ejecución. Ya “sólo” por este “pequeño” problema tenemos ya un agujero del tamaño de un tonel respecto a la protección de tipos en tiempo de diseño. Podemos pedirle lo que quiera al dataset, porque el compilador no va a darnos ningún tipo de alarma, nos vamos a enterar en tiempo de ejecución generando una excepción si la consulta sobre el dataset no era correcta.

Este problema se vuelve más complicado aún si consumimos el servicio desde por ejemplo un cliente java, ya que para interpretar el contenido del dataset en tiempo de ejecución no nos va a quedar más remedio que leer el mensaje xml que nos llega con el contenido, leerlo e interpretarlo a pelo.

¿Cual es entonces mi recomendación? No es difícil respuesta adivinarlo si leéis los artículos de esta web, por mi parte está claro, Data Transfers Objects :) O Value Objects, que es lo mismo :)

Saludos!

Miguel.

Rating 3.00 out of 5
[?]

11.30.07

Buenas Prácticas: Encapsular, encapsular y encapsular.

Posted in Buenas Prácticas, Gestión del Mantenimiento, Programación at 9:52 pm by Miguel

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.

Rating 4.00 out of 5
[?]

« Previous entries Next Page » Next Page »