lunes, 28 de agosto de 2006

La ley de Demetrio

He aquí un claro ejemplo de lo gracioso que puede llegar a ser traducir frases en inglés. En este caso, todo un señor paradigma de la programación orientada a objetos (The Law of Demeter) nos queda reducido a algo que parece el título de una película setentera de Pajares y Esteso.

La susodicha ley especifica un método para construir clases lo más desacopladas e independientes posible, de forma que la reutilización de componentes y el mantenimiento de aplicaciones resulten tareas algo más sencillas. Concretamente, la ley dice que un método de una clase sólo debería invocar métodos pertenecientes a:
  1. El propio objeto.
  2. Los objetos creados por el método.
  3. Los objetos pasados al método como parámetros.
  4. Los campos y propiedades del propio objeto.
Si seguimos esta ley a rajatabla, esto implica, por ejemplo, que no podemos invocar métodos de objetos que nos son devueltos al invocar otros métodos. Esto puede llegar a ser complejo de cumplir.

Otra consecuencia más "razonable" es la ausencia de variables globales. La información de contexto apropiada debería estar contenida en el propio objeto como una propiedad. Aunque esto también parece complejo de cumplir, ahora veremos un ejemplo de cómo hacerlo de forma sencilla.

Tomemos por ejemplo el recurso global por excelencia de cualquier aplicación (por lo menos del tipo de aplicación que yo desarrollo): la conexión a la base de datos. Supongamos que necesitamos un objeto SqlConnection omnipresente, accesible desde cualquier lugar de la aplicación. Lo típico en estos casos es crear una clase estática de estado y almacenar la conexión como una propiedad de la misma. Entonces, las clases que necesitan acceso a la base de datos no tienen más que leer la susodicha propiedad de la susodicha clase.

Pues bien, según Demetrio, esto está MAL.

En primer lugar, la conexión no debería ser accesible a cualquier clase de la aplicación, sino sólo a aquellas de la capa de acceso a datos. Pero eso es otro tema, y tampoco quiero ponerme excesivamente repelente.

En segundo lugar, toda clase que necesite acceso la base de datos debe tener una propiedad que albergue la conexión, de esta guisa:

De esta forma, si en el futuro queremos reutilizar la clase en otro proyecto, podremos hacerlo sin problemas, puesto que no habrá ninguna dependencia de datos globales.

Y tu dirás, "¡Pero yo creo instancias de esa clase en mil sitios en mi código! ¿Tengo que establecer la conexión cada vez? ¡Qué pesadilla!" Y razón no te falta. Pero existe una solución muy sencilla: crear una propiedad estática que contendrá el valor predeterminado para la propiedad, es decir, el valor que tendrán las instancias nuevas si no se especifica lo contrario. Verbigracia:

Ahora sólo tienes que establecer el valor de la propiedad estática una vez, en el método Main que da inicio a la aplicación:

...y si para una instancia en particular quieres establecer otra conexión, puedes hacerlo tranquilamente mediante su propiedad Connection.

Y como hoy estás un poco gruñón, volverás a quejarte: "Vale, pero cada vez que creo una clase nueva con acceso a datos, tengo que acordarme de inicializarle la conexión predeterminada en el Main. Y yo tengo muchas clases y bla bla..." Tranquiiilo, que esto también tiene una solución facilona. Es hora de que la reflexión venga al rescate.

No, no se trata de que nos volvamos filósofos de repente. La reflexión es el mecanismo de .NET que nos permite obtener información sobre los componentes de cualquier ensamblado: podemos listar las clases existentes, los miembros de una clase, invocar métodos especificando su nombre, etc.

Usando reflexión, podemos decirle a nuestra aplicación lo siguiente: "Búscame todas las clases del ensamblado actual que tengan una propiedad llamada DefaultConnection, y les estableces la propiedad con este valor". Dicho y hecho:

Una solución más limpia sería crear un interfaz (por ejemplo IConnectable) que tuviera como propiedad la conexión y su alter-ego estático, y hacer que las clases con derecho a acceso a la base de datos implementaran ese interfaz. Pero eso te lo dejo como ejercicio (que además ya estoy cansado de escribir).

Conclusión: haz caso a Demetrio, que es más viejo que tú y sabe mucho.

Más información aquí.

jueves, 24 de agosto de 2006

Fragmentos de código

Visual Studio 2005 proporciona un mecanismo útil para insertar rápidamente esos pequeños trozos de código que usamos una y otra vez. El mecanismo se llama, precisamente, fragmentos de código (en inglés Code Snippets).

Un fragmento de código se almacena como un fichero XML y consiste en una porción de código fijo con algunos campos variables. Cada fragmento tiene un nombre corto que sirve para invocarlo desde el editor de Visual Studio: basta escribir el nombre del fragmento y pulsar TAB. Todo el código del fragmento aparecerá ante nuestros ojos como por arte de birlibirloque, y podremos movernos entre los campos editables con la tecla TAB. Cuando lo hayamos editado todo a nuestra conveniencia, bastará pulsar ENTER y seguir programando como si nada hubiera pasado.

Haz la prueba. Desde el editor de código de C#, escribe prop y pulsa TAB. Aparecerá tal que esto:


prop es uno de los fragmentos que Visual Studio incorpora de fábrica, y permite añadir propiedades con un campo privado de respaldo (lo cual debe hacerse siempre en vez de usar campos públicos, como todo programador educado sabe). Por supuesto, la gracia del asunto consiste en que puedes definir tus propios fragmentos y añadirlos al arsenal (menú Herramientas - Administrador de fragmentos de código).

Por ejemplo, para mi quehacer diario he creado un fragmento llamado propt basándome en el prop existente. Los cambios son dos: establece como nombre del campo de respaldo el mismo que el de la propiedad, con un carácter de subrayado delante; y añade un boceto de comentario XML. La invocación de propt genera lo siguiente:


Y por si os interesa, teneis el código del fragmento aquí mismo: podeis descargarlo e importarlo desde Visual Studio.

Más información sobre el tema en la web del tito Puertas.

MessageBox.Show("¡Hola!");

Saludos, buena gente. Como bien pone más arriba, en este blog publicaré todo aquello que descubra/se me ocurra/aprenda durante el desempeño de mi empleo como programador en .NET (C# con Visual Studio 2005 en estos momentos) y SQL Server (de nuevo, versión 2005). Más que nada lo hago para tener una especie de copia de seguridad de mi cerebro, para cuando se me vayan olvidando cosas (que la edad no perdona, y la de uno ya tiene seis bits); pero si alguno de estos relatos mitológicos te resulta de utilidad, pues tanto mejor. Huelga decir que vuestros comentarios, si los hubiere, son bienvenidos.

Y tú dirás, "¡Pero bueno! ¡Si tú eres comunista! ¿Cómo es posible que trabajes para el demonio capitalista?" Pues hijo, la vida da muchas vueltas, las cosas vienen tal como vienen, el fútbol es así y uno de cada dos por tres son seis. Todos cometemos locuras en nuestra juventud, y la mía consistió en adentrarme en el mundo de la programación PCera con el infame limitado Visual Basic 6. Para expiar mi culpa, os contaré que en mi empresa actual se programaba en VB.NET cuando yo entré, pero mediante un hábil proceso de lavado cerebral y publicidad subliminal conseguí que nos pasáramos al C#.

Pues eso, que os divirtais, y no olvideis visitar mi otra bitácora.