Entradas para la categoría 'General'

Heredar de un Singleton

Miércoles 19 de Septiembre de 2007 a las 23:56

En un post anterior ya hablé del patrón de diseño Singleton.

Una de las limitaciones de este patrón es la dificultad de crear una clase singleton base y crear varias clases derivadas o hijas que hereden de ella adquiriendo el comportamiento de la clase Padre, lo cual incluye además del comportamiento como singleton cualquier otra funcionalidad común que se desee añadir.

La dificultad parte del hecho de que si declaramos la variable Instancia como static (en C#) o shared (en VB.NET), dicha variable será compartida por todas las clases derivadas.

El problema de heredar de una clase singleton es que al pertenecer la instancia privada (declarada como shared en VB.NET y como static en C#) a la clase padre será compartida por todas las clases derivadas. Por lo que cuando en cada una de las clases derivadas hagamos el GetInstance obtendremos siempre la misma instancia de la misma clase derivada (que será la que realice el primer GetInstance que es donde se instancia dicha clase.

En este artículo se aporta una posible solución a este problema. Para ello realmente no se utiliza herencia sino Generics, aunque el resultado es similar y se da solución al problema planteado.

Las clases "derivadas" (que como ya hemos comentado realmente no heredan de la clase genérica) el único código adicional al que tuvieran que deben incorporar es declarar un constructor privado para evitar que sean instanciadas con lo que se vulneraría uno de los requisitos básicos del patrón singleton que es que solo puede existir una instancia de la clase.

 

VB.NET:
  1. Public Class SingletonGenerico(Of Tipo)
  2.  
  3.     Private Sub New()
  4.     End Sub
  5.  
  6.     Private Shared _instancia As Tipo
  7.  
  8.     Public Shared ReadOnly Property Instancia() As Tipo
  9.         Get
  10.             If _instancia Is Nothing Then
  11.                 _instancia = CType(Activator.CreateInstance(GetType(Tipo), True), Tipo)             
  12.             End If
  13.  
  14.             Return _instancia
  15.         End Get
  16.     End Property
  17.  
  18. End Class

 

La utilización de una clase "MiClase" que tuviera una propiedad llamada "PropiedadDeMiClase" y que hiciera uso de la clase genérica seria la siguiente:

 

VB.NET:
  1. ConfiguracionGenerica(Of MiClase).Instancia.PropiedadDeMiClase = "¡Funciona!"

 

Simulador de vuelo

Domingo 16 de Septiembre de 2007 a las 23:55

Como comente en un post anterior últimamente he estado realizando unas pruebas con la programación gráfica en 3D.

El resultado es un sencillo simulador de vuelo en el que manejas un avión.

(Pulsad la imagen para verla a tamaño real)
Captura del simulador de vuelo.
Captura del simulador de vuelo.

La cámara puede moverse libremente por el mundo o fijarse a la parte delantera del avión o a su parte posterior.

En la parte inferior izquierda se visualiza el velocímetro analógico y la brújula que indica en que dirección te mueves. También se muestra un indicador de la altitud y de la inclinación con respecto al horizonte para saber si estamos ascendiendo o descendiendo y en que medida.
En la esquina inferior derechas se encuentra un pequeño mapa a escala y un punto rojo parpadeante que nos indica en todo momento en donde estamos y que es muy útil para dirigirnos a nuestro destino.

Esta desarrollado en Visual Basic .NET con el Framework 2.0 y haciendo uso de las DirectX 9.

Los gráficos como se puede observar son extremadamente malos.

(Pulsad la imagen para verla a tamaño real)
Captura del simulador de vuelo.
Captura del simulador de vuelo.

 

Plugin para el wordpress: Manejar las descargas

Martes 11 de Septiembre de 2007 a las 23:55

En el área de descargas tengo varios ficheros disponibles para descargar y tengo pensado ir subiendo nuevas descargas a corto plazo. Hasta ahora no tenía forma de saber el número de veces que se descargaban dichos archivos ni de llevar un control de cuando lo subía ni asociarles una descripción.

Un plugin bastante interesante que he encontrado para el wordpress es el download monitor, que puede encontrarse en la siguiente dirección:

http://blue-anvil.com/archives/wordpress-download-monitor-plugin-v15

Con este plugin podremos realizar fácilmente la subida de ficheros a nuestro blog, tener todos los ficheros bien localizados y saber cuantas veces se descarga cada uno. También permite asociar una versión a cada fichero.

Tanto la instalación del plugin como su uso es muy sencillo.

La ruta por defecto a la que se subieran los ficheros es la siguiente /wp-content/plugins/wp-downloadMonitor/user_uploads/
Probablemente deseemos modificar esta ruta indicando otra que nos parezca más adecuada, para ello debemos modificar el fichero wp-downloadMonitor.php. Dicha ruta aparece cableada en el código (Hard code) en 10 puntos de dicho fichero. Y en esos 10 puntos debemos modificarlo por la ruta que deseemos. No se si el desarrollador del plugin habrá tenido alguna razón para hacerlo así, pero lo razonable parece que hubiera sido meter ese valor en la base de datos y permitir modificarlo desde la pantalla de opciones o en el peor de los casos tenerlo una única vez en el código en vez de diez veces.

Además he tenido que modificar también los tipos de ficheros permitidos para subir y descargar, ya que inicialmente solo se permitían los .zip y los .pdf

Un plugin muy recomendable de incorporar a nuestro blog y con el que de momento no he tenido ningún problema.

Herramienta para obtener el color de un pixel de la pantalla.

Domingo 9 de Septiembre de 2007 a las 23:56

Esta sencilla herramienta la desarrollé hace algo más de dos años y permite conocer el color de un determinado pixel de la pantalla. Dicho color es expresado por sus componentes ARGB tanto en hexadecimal como en decimal.
Esta herramienta puede ser útil si por ejemplo queremos poner un control de una pagina html o de una aplicación windows de un determinado color (que aparezca en otra pagina web o en una imagen) y no sabemos su representación para reproducirlo.

Su funcionamiento es muy sencillo. Tiene dos modos, capturar y no capturar. En el modo capturar se obtendrá el color del pixel sobre el cual posicionemos el ratón. Para cambiar de modo se debe pulsar la tecla "Espacio". También se puede pulsar con el ratón sobre el check de capturar, pero entonces se modificará el color obtenido ya que cambiamos de posición el ratón.

Esta desarrollada en Visual Basic.NET haciendo uso del Framework 1.1. Para implementarlo hice uso del API de windows.

En la sección de descargas podréis obtener tanto el código fuente como los binarios de al aplicación.

Este es el aspecto que tiene la herramienta:

Herramienta Color.
Herramienta Color.

 

Descarga añadida: Control Borde

Lunes 30 de Julio de 2007 a las 23:39

He añadido en la sección de descargas el código completo del control borde del que hablé en un post anterior y que permite dotar a los controles de .NET de varios estilos de borde adicionales a los que vienen por defecto.

Primer aniversario

Domingo 29 de Julio de 2007 a las 23:54

Hoy se cumple el primer aniversario del nacimiento de este blog.

En estos 365 días he publicado 44 posts, a una media de un post cada ocho días y se han recibido 95 comentarios. El número de mensajes de spam recibidos asciende a más de 7000.
El número de visitas únicas ha sido de 9.808, que han visto 17.468 páginas. Muchos de ellos han sido gente despistada que ha llegado a través de google buscando otras cosas.

En cuanto al proyecto, no ha avanzado todo lo que hubiera querido debido a la falta de tiempo, aunque poco a poco va avanzando y ya hay algunas cosas visibles que espero mostrar en breve.

Singleton más legible y accesible en VB.NET

Jueves 26 de Julio de 2007 a las 23:59

Uno de los patrones de diseño más conocidos y utilizados (si no el que más) es el patrón singleton, que permite garantizar la existencia de una única instancia de una clase evitando la creación de objetos de ese tipo declarando el constructor como privado o protegido. Otra de las ventajas de este patrón es que permite centralizar en un único punto todos los accesos a la instancia.

Una posible implementación en Visual Basic .NET sería la siguiente:

 

VB.NET:
  1. Public Class Singleton
  2.  
  3.     Private Sub New()
  4.     End Sub
  5.  
  6.     Private Shared _instancia As Singleton
  7.  
  8.     Public Shared ReadOnly Property Instancia() As Singleton
  9.         Get
  10.             If _instancia Is Nothing Then
  11.                 _instancia = New Singleton
  12.             End If
  13.  
  14.             Return _instancia
  15.         End Get
  16.     End Property
  17. End Class

 

La forma de acceder a una propiedad de esta clase para asignarle un valor sería:

Singleton.Instancia.MiPropiedad = "miValor"

Esta forma de acceder a una propiedad es un poco artificial y no resulta tan legible o natural como:

Singleton.MiPropiedad = "miValor"

Para conseguir acceder de estar forma a una propiedad de nuestra instancia deberemos crearnos un modulo:

 

VB.NET:
  1. <Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
  2. Public Module Auxiliar
  3.     Public ReadOnly Property SingletonInst() As Singleton
  4.         Get
  5.             Return Singleton.Instancia
  6.         End Get
  7.     End Property
  8. End Module

 

Ahora para acceder a la propiedad simplemente tendremos que escribir:

SingletonInst.MiPropiedad = "miValor"

Esta solución únicamente es valida en Visual Basic.NET debido a que en C# no existen los módulos.

Detectar los cambios de la IP

Martes 24 de Julio de 2007 a las 23:51

A la hora de contar las visitas que tiene un sitio web es interesante no computar tus propias visitas que en algunos momentos pueden llegar a ser numerosas y que falsean las estadísticas reales. Para evitar esto los sistemas de estadísticas como el statcounter o el Google Analytics cuentan con la posibilidad de no contabilizar las visitas provenientes de una determinada IP.

El problema es que es bastante común tener direcciones IP dinámicas que cambian de vez en cuando, lo que obliga a tener que estar comprobando frecuentemente si tu IP actual coincide con la que estás filtrando en los servicios de estádisticas y si no es así actualizar las IP de los filtros.

En el caso de que se olvide hacer esta comprobación y cambies de IP las estadísticas habrán estado contando todas tus visitas.

Para evitar está situación he creado una pequeña aplicación en Visual Basic.NET que apenas cuenta con media docena de líneas de código y que configurada para que se arranque al iniciar windows realizará la comparación de la IP actual y la anterior IP y en el caso de que sea diferente mostrará un aviso.

En el área de descargas está disponible el ejecutable.

El código de esta pequeña aplicación creada en VB.NET es el siguiente:

 

VB.NET:
  1. Option Strict On
  2. Option Explicit On
  3.  
  4. Module Programa
  5.  
  6.     Sub Main()
  7.         Dim IPs As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName())
  8.  
  9.         If IPs.AddressList(0).ToString <> My.Settings.IP Then
  10.             MsgBox("Ha cambiado la IP de la máquina", MsgBoxStyle.Information, "Atención")
  11.             My.Settings.IP = IPs.AddressList(0).ToString
  12.             My.Settings.Save()
  13.         End If
  14.     End Sub
  15.  
  16. End Module

Dotando a los controles de .NET de un borde personalizado

Miércoles 18 de Julio de 2007 a las 23:57

Sorprendentemente los controles de .NET no admiten apenas estilos de borde. Por ejemplo el control listbox solo permite dibujar el borde de tres formas: hundido, con una línea negra o sin borde.

El intellisense que desarrollé hace tiempo para el editor de código se basaba en un listbox y no tenía una apariencia adecuada ni similar a los del intellisense de los IDES habituales debido al borde que tenía que era el borde hundido que viene por defecto en dicho control.

La primera forma de implementar los bordes que me vino a la cabeza fue crear un control que heredara de listbox, es la forma más lógica de implementarlo debido a lo que se busca es un listbox con cierta funcionalidad adicional. Sin embargo el control listbox no implementa el evento paint y aunque lo hereda de la clase Control nunca se levanta. De igual forma si se sobrescribe el método onpaint tampoco se ejecuta nunca.

La siguiente opción que se me ocurrió fue crear un control de usuario compuesto de un listbox y un picturebox, un panel o similar que contuviera el listbox y que sobresaliera dos pixels por cada uno de los lados del listbox. En esos pixeles sería donde dibujaría los bordes valiéndome del evento paint. Esta opción tiene un importante inconveniente y es que al no heredar de listbox sino de la clase UserControl no implementa todos los métodos, propiedades y eventos de listbox. En este punto habría dos opciones, la fácil que consistiría en hacer publico el listbox. Esta opción rompe con uno de los pilares de la orientación a objetos que es la encapsulación y el código que utilizara el control tendría que hacer utilizar por ejemplo listBoxConBorde.ListboxInterno.SelectedIdex en vez de listBoxConBorde.SelectedIdex que sería lo deseable.
La otra opción sería recubrir las propiedades, métodos y eventos del listbox en el control de usuario, creando en el control de usuario tantas propiedades, métodos y eventos como tenga el listbox. Estos miembros del control de usuario simplemente llamarían a los miembros homónimos del listbox. Esta opción me parece más adecuada que la anterior pero mucho mas tediosa de implementar.

Finalmente opté por una solución que me ha parecido mucho más acertada, sencilla y genérica. Consiste en crear un control llamado "Borde" que dibuje el borde de cualquier control. Hereda de la clase "Control" y consta de dos propiedades:

  • El tipo de borde (que admite los siguientes valores Elevado, ElevadoDobleLinea, Hundido, ElevadoYHundido y HundidoYElevado)
  • El control asociado al que se le dibujará el borde.

Además del código para realizar el dibujo del borde también se encarga de adecuar su tamaño y posición a la del control asociado.

Extender el control para añadir nuevos tipos de bordes con diferentes efectos sería una labor bastante sencilla de realizar.

La nueva apariencia del intellisense estableciendo el borde a ElevadoDobleLinea es la siguiente:


Intellisense con el nuevo borde.
Intellisense con el nuevo borde.


Intellisense."
Intellisense anterior.

 

En la sección de descargas se puede encontrar el código completo en VB.NET del control.

Combatiendo el spam

Martes 17 de Julio de 2007 a las 23:58

Después de bastante tiempo sin escribir ningún post y tener también abandonada la programación de videojuegos retomo ambas actividades.

En todo este tiempo en blog se me ha llenado de spam, no 3 o 4 comentarios, sino miles de ellos (en torno a 7000). Espero no haber borrado ningún comentario que no fuera spam por error durante las tareas de limpieza del blog.

Parece que es bastante habitual recibir spam en los blogs basados en wordpress.

Para evitar esta situación he decidido instalar un plugin antispam llamado wordverify. Este plugin se puede encontrar gratuitamente en esta página. De momento esta funcionando bien y no me ha llegado ni un solo comentario de spam desde que lo instalé. El original no funcionaba del todo correctamente así que he tenido que hacerle algunas modificaciones para corregirlas además de para traducir los textos. Si alguien está interesado que me lo pida. Se basa en solicitar a la persona que va a escribir el comentario que escriba una determinada palabra en una caja de texto con el fin de diferenciar a las personas y a los procesos automáticos de envio de Spam.

Para combatir el spam que llegaba mediante los trackbacks he utilizado el plugin Simple Trackback Validation que parece funcionar también correctamente.

Espero que estos plugins no presente ningún efecto secundario adverso. Si alguien tiene algún problema para escribir comentarios o de cualquier tipo con los filtros antispam por favor que me lo comunique a mi dirección de email brauXsoftYgmailZcom (eliminad la X, sustituid la Y por @ y la Z por .)