March 2011 - Artículos
.gif)
Patrón Observador en .NET - pattern Observer
Introducción
El patrón observador (pattern Observer) es uno de los
patrones que más me gustan, motivo principal por el cual me he animado a
escribir esta entrada para que lo muestre de una forma práctica, agradable y
útil para en primer lugar entenderlo, y posteriormente ser implementado en
nuestros desarrollos de .NET.
Espero que esta entrada os ayude a entender mejor el
funcionamiento de este patrón y os brinde la posibilidad de valorarlo por si os
interesa utilizarlo en vuestros desarrollos, o implementar un híbrido que os
resulte útil para abordar determinados problemas con los que os podáis
encontrar durante vuestros desarrollos Software.
Visión general del patrón
Este patrón se define como un patrón de tipo relacional de
uno a muchos.

De esta forma, un subscriptor (también denominado en algunas
ocasiones como observador) es el encargado de subscribirse a un publicador.
El publicador es a su vez el encargado de notificar que ha
sucedido “algo” que requiere la atención de sus subscritores.
En este punto, el publicador estará relacionado con todos
sus subscriptores, y cuando ocurra “algo”, todos los subscriptores se darán por
enterados.
Lógicamente, debe haber un mecanismo que permita agregar un
subscriptor y eliminar al subscriptor, tanto para que reciba notificaciones
como para que deje de recibirlas.
Aquí tampoco se está analizando la casuística de que con
determinados sucesos, el publicador sólo comunique que ha sucedido algo a unos
determinados subscriptores y a otros no. Simplemente vamos a analizar el caso
general de este patrón en el que todos los subscriptores reciben la
comunicación de aviso (notificación) por parte del publicador.
Aproximación 1
Vamos a empezar por lo tanto a preparar nuestra primera
implementación del patrón Observador.
Se trata de una implementación generalista.
Es decir, partiremos de la base de crear una biblioteca de
clases cuyo proyecto denominaré PatternObserver
para crear en él las clases que permitan comprender y utilizar este patrón.
También crearé un proyecto adicional de tipo WinForms que utilizaré para probar la
implementación del patrón y demostrar su funcionamiento en esta primera
aproximación.
PatternObserver
El diagrama general de lo que vamos a crear es lo que se
puede observar en la siguiente imagen:

Aquí podemos observar un proyecto PatternObserver que
contendrá las siguientes clases:
-
IObserver
-
ISubject
-
Subject
La explicación de cada una de estas clases es la siguiente:
IObserver es la
interfaz que define qué debe notificarse a cada uno de los subscriptores u
observadores para indicarles que ha sucedido “algo” y que requiere de su atención.
Más adelante veremos cómo funciona esto realmente, pero lo que tenemos que
tener en cuenta es que contiene un método llamado UpdateState() que se
encarga de actualizar ese estado o hecho.
ISubject es la
interfaz que define las acciones que pueden acometerse con respecto a cada uno
de sus observadores. Es decir, conoce a sus observadores y le permite
subscribirse, desubscribirse, y notificar a todos y cada uno de sus
subscriptores la notificación correspondiente (en nuestro caso, llamar a UpdateState()).
Subject es para
esta primera aproximación una clase que implementa ISubject y que es
consumida por la aplicación de ejemplo y demostración del funcionamiento y uso
de este patrón. Como vemos, para esta primera aproximación he querido crear un
proyecto que contenga esta clase también como clase que contenga esta
funcionalidad y que muestre como generarla a partir de ISubject, algo que
haremos en la segunda aproximación para mostrar las dos opciones generales.
El diagrama general de clases del proyecto es el que se
indica a continuación:

El código de nuestras clases es el que se indica a
continuación:
IObserver
namespace PatternObserver
{
/// <summary>
/// Interface del patrón Observer.
/// </summary>
public interface IObserver
{
/// <summary>
/// Método encargado de indicar que el estado del proceso debe actualizarse para que
/// indique a los observadores "algo".
/// </summary>
/// <param name="sender">Indicamos la interfaz a quién se le envía la notificación.</param>
void UpdateState(ISubject sender);
} // IObserver
} // PatternObserver
ISubject
namespace PatternObserver
{
/// <summary>
/// Interface del patrón Observer.
/// </summary>
public interface ISubject
{
/// <summary>
/// Método encargado de notificar a todos y cada uno de los observadores que ha
/// sucedido "algo".
/// Esto se realiza recorriendo todos los observadores subscritos y ejecutando por
/// cada uno de ellos el método UpdateState() implementado de IObserver.
/// </summary>
void Notify();
/// <summary>
/// Método encargado de subscribir un observador para que reciba las notificaciones.
/// </summary>
/// <param name="observer">Interfaz IObserver que indica el observador.</param>
void Subscribe(IObserver observer);
/// <summary>
/// Método encargado de desubscribir un observador para que no reciba más
/// notificaciones.
/// </summary>
/// <param name="observer">Interfaz IObserver que indica el observador.</param>
void Unsubscribe(IObserver observer);
} // ISubject
} // PatternObserver
Subject
namespace PatternObserver
{
using System.Collections.Generic;
/// <summary>
/// Clase encargada de implementar la interfaz ISubject para permitir registrar un
/// observador, eliminar el registro de un observador y notificarle que ha sucedido "algo".
/// </summary>
public class Subject : ISubject
{
#region CONSTRUCTORS
/// <summary>
/// Constructor de la clase.
/// </summary>
public Subject()
{
// Instanciamos la colección de observadores.
this.Observers = new List<object>();
} // Subject Constructor
#endregion
#region PROPERTIES
/// <summary>
/// Propiedad privada encargada de contener todos los subscriptores.
/// </summary>
private List<object> Observers { get; set; }
#endregion
#region METHODS
/// <summary>
/// Método encargado de notificar al subscriptor que ha sucedido un evento que
/// requiere su atención.
/// </summary>
public void Notify()
{
// Recorremos cada uno de los observadores para notificarles el evento.
foreach (IObserver observer in this.Observers)
{
// Indicamos a cada uno de los subscriptores la actualización del
// estado (evento) producido.
observer.UpdateState(this);
}
} // Notify
/// <summary>
/// Método encargado de agregar un observador para que el subscriptor le
/// pueda notificar al subscriptor el evento.
/// </summary>
/// <param name="observer">Interfaz IObserver que indica el observador.</param>
public void Subscribe(IObserver observer)
{
// Agregamos el subscriptor a la lista de subscriptores del publicador.
this.Observers.Add(observer);
} // Subscribe
/// <summary>
/// Método encargado de eliminar un observador para que el subscriptor no le
/// notifique ningún evento más al que era su subscriptor.
/// </summary>
/// <param name="observer">Interfaz IObserver que indica el observador.</param>
public void Unsubscribe(IObserver observer)
{
// Eliminamos el subscriptor de la lista de subscriptores del publicador.
this.Observers.Remove(observer);
} // Unsubscribe
#endregion
} // Subject
} // PatternObserver
En este caso, he creado una clase (Subject) que implementa
la interfaz ISubject y que tiene varias partes diferenciadoras.
En primer lugar he creado una propiedad (Observers)
que contendrá una lista de todos y cada uno de los observadores. Lógicamente,
habrá que crear la vía o forma de registrar y eliminar del registro a un
observador determinado. Esto lo haremos de acuerdo a la implementación de los
métodos de la interfaz.
Por lo tanto, en la implementación de la interfaz
prepararemos los tres métodos de la misma. El método Subscribe se encarga de
registrar o insertar en la lista de observadores a un observador concreto,
mientras que el método Unsubscribe se encarga de eliminar
de la lista de observadores al observador en cuestión.
Indudablemente, tendremos que trabajar en el método Notify
de una manera particular, y es que dentro de este método tendremos la
obligación de recorrer todos y cada uno de los observadores registrados y
llamar al método UpdateState() que se encargará de realizar la acción concreta
que tenga que hacer y que implementaremos y veremos más adelante.
PatternObserverProject
Sobre el proyecto de aplicación Windows de ejemplo (PatternObserverProject),
este está formado por las siguientes clases:
-
MainForm
-
SampleObserver
La explicación de cada una de estas clases es la siguiente:
MainForm es la
clase formulario con diferentes controles de usuario y las acciones generales
que forman parte de la demostración de uso de este patrón.
SampleObserver es
la clase que implementa la interfaz IObserver y determina qué acción o
acciones realiza en realidad UpdateState().
El diagrama general de clases del proyecto es el que se
indica a continuación:

Para esta primera aproximación, he preparado una interfaz de
usuario similar a la que se indica en la siguiente imagen:

Este ejemplo tiene tres botones que se encargan cada uno de
ellos de añadir un observador a la lista de observadores. Al hacer clic sobre
uno de estos botones se deshabilitará su control Button y se habilitará el homónimo pero para eliminar el observador
correspondiente.
Finalmente, el botón de lanzar el evento, es el encargado de
simular que ocurre “algo” y que los observadores deberán darse cuenta de que
han sido informados de que ha pasado algo que requiere su atención.
Como es un ejemplo de demostración, ese “algo” es un mensaje
en pantalla que nos va a indicar que observador es. Si registramos los tres
observadores y pulsamos el botón de lanzar el evento, aparecerán tres mensajes
en pantalla, uno por cada observador.
El código de nuestras clases es el que se indica a
continuación:
MainForm
namespace PatternObserverProject
{
using System;
using System.Windows.Forms;
/// <summary>
/// Clase formulario de ejemplo y demostración del patrón Observer.
/// </summary>
public partial class MainForm : Form
{
#region CONSTRUCTORS
/// <summary>
/// Clase principal del formulario.
/// </summary>
public MainForm()
{
InitializeComponent();
} // MainForm
#endregion
#region EVENTS
/// <summary>
/// Evento MainForm_Load encargado de ejecutarse al cargar el formulario
/// Windows de prueba para el patrón Observer.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Load(object sender, EventArgs e)
{
// Instanciamos a PatternObserver.Subject.
this.SubjectDemo = new PatternObserver.Subject();
} // MainForm_Load
/// <summary>
/// Evento encargado de subscribirse al publicador.
/// Este evento simula al primer subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddFirst_Click(object sender, EventArgs e)
{
this.btnRemoveFirst.Enabled = this.btnAddFirst.Enabled;
this.btnAddFirst.Enabled = !this.btnAddFirst.Enabled;
// Inicializamos la clase Observer correspondiente.
// Simulamos la subscripción a Observer.
this.Observer1 = new SampleObserver("Observador 1");
this.SubjectDemo.Subscribe(this.Observer1);
} // btnAddFirst_Click
/// <summary>
/// Evento encargado de eliminar la subscripción al publicador.
/// Este evento simula al primer subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveFirst_Click(object sender, EventArgs e)
{
this.btnRemoveFirst.Enabled = this.btnAddFirst.Enabled;
this.btnAddFirst.Enabled = !this.btnRemoveFirst.Enabled;
// Simulamos la eliminación de la subscripción a Observer.
this.SubjectDemo.Unsubscribe(this.Observer1);
} // btnRemoveFirst_Click
/// <summary>
/// Evento encargado de subscribirse al publicador.
/// Este evento simula al segundo subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddSecond_Click(object sender, EventArgs e)
{
this.btnRemoveSecond.Enabled = this.btnAddSecond.Enabled;
this.btnAddSecond.Enabled = !this.btnAddSecond.Enabled;
// Inicializamos la clase Observer correspondiente.
// Simulamos la subscripción a Observer.
this.Observer2 = new SampleObserver("Observador 2");
this.SubjectDemo.Subscribe(this.Observer2);
} // btnAddSecond_Click
/// <summary>
/// Evento encargado de eliminar la subscripción al publicador.
/// Este evento simula al segundo subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveSecond_Click(object sender, EventArgs e)
{
this.btnRemoveSecond.Enabled = this.btnAddSecond.Enabled;
this.btnAddSecond.Enabled = !this.btnRemoveSecond.Enabled;
// Simulamos la eliminación de la subscripción a Observer.
this.SubjectDemo.Unsubscribe(this.Observer2);
} // btnRemoveSecond_Click
/// <summary>
/// Evento encargado de subscribirse al publicador.
/// Este evento simula al tercer subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddThird_Click(object sender, EventArgs e)
{
this.btnRemoveThird.Enabled = this.btnAddThird.Enabled;
this.btnAddThird.Enabled = !this.btnAddThird.Enabled;
// Inicializamos la clase Observer correspondiente.
// Simulamos la subscripción a Observer.
this.Observer3 = new SampleObserver("Observador 3");
this.SubjectDemo.Subscribe(this.Observer3);
} // btnAddThird_Click
/// <summary>
/// Evento encargado de eliminar la subscripción al publicador.
/// Este evento simula al tercer subscriptor.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveThird_Click(object sender, EventArgs e)
{
this.btnRemoveThird.Enabled = this.btnAddThird.Enabled;
this.btnAddThird.Enabled = !this.btnRemoveThird.Enabled;
// Simulamos la eliminación de la subscripción a Observer.
this.SubjectDemo.Unsubscribe(this.Observer3);
} // btnRemoveThird_Click
/// <summary>
/// Evento encargado de simular una llamada al proceso que desencadena que los
/// subscriptores asociados al publicador reciban el evento de que se ha
/// desencadenado la acción.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnExecuteEvent_Click(object sender, EventArgs e)
{
// Lanzamos la notificación del proceso.
this.SubjectDemo.Notify();
} // btnExecuteEvent_Click
#endregion
#region PROPERTIES
/// <summary>
/// Propiedad encargada de instanciar a PatternObserver.Subject.
/// </summary>
private PatternObserver.Subject SubjectDemo { get; set; }
/// <summary>
/// Propiedad que utiliza la clase que implementa a Observer.
/// </summary>
private SampleObserver Observer1 { get; set; }
/// <summary>
/// Propiedad que utiliza la clase que implementa a Observer.
/// </summary>
private SampleObserver Observer2 { get; set; }
/// <summary>
/// Propiedad que utiliza la clase que implementa a Observer.
/// </summary>
private SampleObserver Observer3 { get; set; }
#endregion
} // MainForm
} // PatternObserverProject
SampleObserver
namespace PatternObserverProject
{
/// <summary>
/// Clase que implementa el patrón Observer.
/// </summary>
public class SampleObserver : PatternObserver.IObserver
{
#region CONSTRUCTORS
/// <summary>
/// Constructor de la clase.
/// </summary>
/// <param name="text">Parámetro utilizado para demostrar la implementación
/// correcta del patrón Observer.</param>
public SampleObserver(string text)
{
// Indicamos el valor de la propiedad Text.
this.Text = text;
} // SampleObserver Constructor
#endregion
#region PROPERTIES
/// <summary>
/// Propiedad que es utilizada para saber qué instancia del subscriptor es lanzada
/// en la notificación.
/// </summary>
private string Text { get; set; }
#endregion
#region IObserver Members
/// <summary>
/// Método utilizado para ser llamado desde el notificador ante un determinado
/// evento que ha sucedido en un momento dado y que requiere la atención por
/// todos y cada uno de los observadores o subscriptores.
/// </summary>
/// <param name="sender">Indicamos la interfaz a quién se le envía la notificación.</param>
public void UpdateState(PatternObserver.ISubject sender)
{
System.Windows.Forms.MessageBox.Show(this.Text);
} // UpdateState
#endregion
} // SampleObserver
} // PatternObserverProject
Esta última clase implementa la interfaz IObserver.
De esta manera, implementamos el método UpdateState(). Como
podemos apreciar, este método llama a MessageBox.Show() para mostrar un
mensaje en pantalla con el valor de la propiedad Text.
Como podemos apreciar es un ejemplo muy sencillo.
Si ejecutamos nuestra aplicación, veremos que ésta se
comporta tal y como esperamos. Es decir, hacemos clic en los botones que
queramos para agregar observadores a la lista de observadores, y posteriormente
hacemos clic en el botón de lanzar evento.
Aproximación 2
La segunda aproximación es prácticamente banal una vez vista
la aproximación anterior.
En la aproximación anterior hemos creado las interfaces y la
clase Subject como implementación general para mostrar una forma
particular y global del uso del patrón.
Si queremos implementar nuestra propia aproximación, quizás
deberíamos tirar directamente de la interfaz.
PatternObserver
El diagrama general de lo que vamos a crear es lo que se
puede observar en la siguiente imagen:

Esta imagen muestra claramente lo que comentaba
anteriormente.
El proyecto de biblioteca de clases PatternObserver contiene
únicamente las interfaces IObserver
e ISubject.
El diagrama general de clases del proyecto es el que se
indica a continuación:

El código y las explicaciones que daba anteriormente son las
mismas.
PatternObserverProject
El proyecto de aplicación Windows (PatternObserverProject)
en este caso, estará formado por las siguientes clases:
-
MainForm
-
SampleObserver
-
SampleSubject
La explicación de estas clases también la hemos comentado
anteriormente.
La única cosa a tener en cuenta es que SampleSubject es una clase del proyecto de prueba que implementa a ISubject.
Para hacer este ejemplo un poco diferente, he modificado
levemente esta clase. En lugar de utilizar un List<object> para
registrar los observadores, he utilizado un ArrayList.
El diagrama general de clases del proyecto es el que se
indica a continuación:

Para esta segunda aproximación, he incluido seis controles Button
más a la interfaz de usuario tal y como se indica en la siguiente imagen:

Finalmente, incluiremos el código de nuestras clases:
MainForm
...
/// <summary>
/// Evento encargado de simular una llamada al proceso que desencadena que los
/// subscriptores asociados al publicador reciban el evento de que se ha
/// desencadenado la acción.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnExecuteEvent_Click(object sender, EventArgs e)
{
// Lanzamos la notificación del proceso.
this.SubjectDemo.Notify();
// Lanzamos la notificación del proceso.
this.InternalSubjectDemo.Notify();
} // btnExecuteEvent_Click
...
/// <summary>
/// Evento MainForm_Load encargado de ejecutarse al cargar el formulario
/// Windows de prueba para el patrón Observer.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Load(object sender, EventArgs e)
{
// Instanciamos a PatternObserver.Subject.
this.SubjectDemo = new PatternObserver.Subject();
// Instanciamos a SampleSubject que implementa la interfaz ISubject.
this.InternalSubjectDemo = new SampleSubject();
} // MainForm_Load
...
/// <summary>
/// Propiedad que utiliza la clase que implementa a Observer.
/// </summary>
private SampleObserver ObserverInternal1 { get; set; }
/// <summary>
/// Propiedad que utiliza la clase que implementa a Observer.
/// </summary>
private SampleObserver ObserverInternal2 { get; set; }
/// <summary>
/// Propiedad encargada de instanciar la clase SampleSubject que implementa
/// PatternObserver.ISubject.
/// </summary>
private SampleSubject InternalSubjectDemo { get; set; }
...
private void btnAddOne_Click(object sender, EventArgs e)
{
this.btnRemoveOne.Enabled = this.btnAddOne.Enabled;
this.btnAddOne.Enabled = !this.btnAddOne.Enabled;
// Inicializamos la clase Observer correspondiente.
// Simulamos la subscripción a Observer.
this.Observer1 = new SampleObserver("Observador 1 - Internal");
this.InternalSubjectDemo.Subscribe(this.Observer1);
}
private void btnRemoveOne_Click(object sender, EventArgs e)
{
this.btnAddOne.Enabled = this.btnRemoveOne.Enabled;
this.btnRemoveOne.Enabled = !this.btnRemoveOne.Enabled;
// Simulamos la eliminación de la subscripción a Observer.
this.InternalSubjectDemo.Unsubscribe(this.Observer1);
}
private void btnAddTwo_Click(object sender, EventArgs e)
{
this.btnRemoveTwo.Enabled = this.btnAddTwo.Enabled;
this.btnAddTwo.Enabled = !this.btnAddTwo.Enabled;
// Inicializamos la clase Observer correspondiente.
// Simulamos la subscripción a Observer.
this.Observer2 = new SampleObserver("Observador 2 - Internal");
this.InternalSubjectDemo.Subscribe(this.Observer2);
}
private void btnRemoveTwo_Click(object sender, EventArgs e)
{
this.btnAddTwo.Enabled = this.btnRemoveTwo.Enabled;
this.btnRemoveTwo.Enabled = !this.btnRemoveTwo.Enabled;
// Simulamos la eliminación de la subscripción a Observer.
this.InternalSubjectDemo.Unsubscribe(this.Observer2);
}
...
Aquí únicamente indico aquellas partes que se crean y
modifican en esta clase.
SampleSubject
namespace PatternObserverProject
{
using System.Collections;
/// <summary>
/// Clase que implementa en este caso la clase ya preparada denominada Subject.
/// Podríamos implementar ISubject y a partir de ella preparar todos sus métodos y
/// acciones, pero esta clase define como reutilizar una clase ya preparada para el
/// propósito del patrón Observer.
/// </summary>
public class SampleSubject : PatternObserver.ISubject
{
#region CONSTRUCTORS
/// <summary>
/// Constructor de la clase.
/// </summary>
public SampleSubject()
{
// Instanciamos la colección de observadores.
this.Observers = new ArrayList();
} // SampleSubject Constructor
#endregion
#region PROPERTIES
/// <summary>
/// Propiedad privada encargada de contener todos los subscriptores.
/// </summary>
private ArrayList Observers {get; set;}
#endregion
#region ISubject Members
/// <summary>
/// Método encargado de notificar al subscriptor que ha sucedido un evento que
/// requiere su atención.
/// </summary>
public void Notify()
{
// Recorremos cada uno de los observadores para notificarles el evento.
foreach (PatternObserver.IObserver observer in this.Observers)
{
// Indicamos a cada uno de los subscriptores la actualización del
// estado (evento) producido.
observer.UpdateState(this);
}
} // Notify
/// <summary>
/// Método encargado de agregar un observador para que el subscriptor le
/// pueda notificar al subscriptor el evento.
/// </summary>
/// <param name="observer"></param>
public void Subscribe(PatternObserver.IObserver observer)
{
// Agregamos el subscriptor a la lista de subscriptores del publicador.
this.Observers.Add(observer);
} // Subscribe
/// <summary>
/// Método encargado de eliminar un observador para que el subscriptor no le
/// notifique ningún evento más al que era su subscriptor.
/// </summary>
/// <param name="observer"></param>
public void Unsubscribe(PatternObserver.IObserver observer)
{
// Eliminamos el subscriptor de la lista de subscriptores del publicador.
this.Observers.Remove(observer);
} // Unsubscribe
#endregion
} // SampleSubject
} // PatternObserverProject
En este caso, esta clase implementa la interfaz ISubject e implementa sus métodos
correspondientes.
Conclusiones
En esta entrada hemos visto cómo implementar en .NET el
patrón Observador (pattern Observer) y como funciona.
A partir de aquí, es cuestión de analizar si este
patrón nos resulta útil e incluso la posibilidad de utilizar un patrón
Observador modificado que satisfaga nuestras necesidades. Sin embargo, he
creído interesante y útil hablar de este patrón que muchos desconocen u
olvidan.
Descarga del proyecto en Visual Studio 2010 (PatternObserverProject.zip - 31 Kb).

Introducción
El 23 de Marzo de 2011 tendremos de 19:00 horas a 21:00 horas un evento en MAD.NUG que versará sobre una mesa redonde en la que discutiremos aquellos aspectos, dudas, preguntas, etc., sobre la gestión de código fuente en nuestros proyectos.
Organización, formas de realizarlo, etc.... en sí es un brainstorming donde cada uno expondrá sus experiencias y sus dudas, sus temores y sus trucos.
Objetivos
No se trata de alabar o de solo hablar de TFS, sino hablar de repositorios de código en general, buenas prácticas, etc., incluyendo otros gestores de código y compartiendo experiencias. :)
¿Te vienes?.
¿Dónde?
En Madrid (España), en Aula Vulcan (gracias a DotNetManía por apoyarnos y facilitarnos la sala):
AULA VULCAN
Calle de Francisco Silvela, 54 duplicado- 1ºD
Madrid 28028
España
Registro
Haz clic aquí para registrarte y acceder a los detalles del evento.
¡Nos vemos!

Introducción
Hace poco comenté en mi blog en un comentario al respecto de Internet Explorer 9 que Firefox 4 era la última versión en camino.
Juraría que ví el otro día en mi navegador un aviso de actualización de Firefox a la 4.0, pero después de responder los comentarios y revisar al día siguiente Firefox, observé que ese aviso había desaparecido, así que pensé en que todo se debía a un error visual.
Ahora después de la noticia oficial por parte del equipo de Firefox y de su versión 4.0, tengo mis dudas de que hubiera visto realmente mal el aviso.
Sea como fuese, el caso es que tenemos ya nueva versión de Firefox, ahora sí que sí. Se trata de la 4.0.
Rendimiento
Según rezan los comentarios del equipo de Firefox, esta nueva versión es 6 veces más rápida que la versión 3.6.
Algo que de ser así, es una ventaja en cuanto a la experiencia de usuario y teniendo en cuenta que los navegadores web son cada vez más pesados (plugins, etc).
Mejoras
Indudablemente, las mejoras tiene su énfasis especial en HTML5.
Su barra de navegación es similar a la de Chrome y a la que ha agregado recientemente IE9.
Otra de las mejoras tiene que ver con la aceleración hardware, algo sobre lo que Microsoft ha golpeado primero y que habrá que ver que diferencias existen con sus competidores.
También es destacable la mejora de lo que denominan "protección ante cuelgues".
Descarga
Podrás acceder a la descarga de Firefox 4.0 en este enlace.

Introducción
El equipo de Microsoft Visual Studio, ha publicado una nueva actualización de esta herramienta.
Nueva versión
Esta nueva versión resuelve sobre todo algún error encontrado en la anterior actualización, así que mi recomendación es que instales la nueva versión.
Instalación
Podrás descargar las Productivity Power Tools desde el enlace de Microsoft Visual Studio Gallery que encontrarás en este enlace.

Si hace unos días me hacía eco de la nueva versión de Microsoft Visual Studio LightSwitch Beta 2, ahora le llega el turno a Microsoft Visual Studio LightSwitch Beta 2 Training Kit.
El material que ocupa poco más de 48 Mb contiene demostraciones y laboratorios fundamentales.
Todo el material está en inglés, y puede ser descargado desde este enlace.

Muy buena noticia la que ha anunciado hoy el equipo de Microsoft Visual Studio 2010 LightSwitch, y es que han liberado la Beta 2 del producto.
De momento, sólo los subscriptores de MSDN podrán acceder a esta herramienta de momento, aunque ese acceso privilegiado apenas durará 2 días, ya que el resto de mortales, podrá descargarse esta nueva versión el próximo jueves 17 de Marzo.
Podrás acceder a los enlaces de descarga en este enlace.
Pero una de las novedades más destacables de esta Beta 2 es que posee una licencia Go Live.
Es decir, que podemos empezar a utilizar Microsoft Visual Studio LighSwitch en entornos de producción.
Ahora bien, si lo que quieres es instalar desde ya esta nueva beta de LighSwitch, debes saber que necesitas el SP1 de Visual Studio 2010 antes de continuar.
Recuerda igualmente, que LighSwitch no se instalará en versiones Express de Visual Studio 2010, y que si tienes instalada Microsoft Visual Studio 2010 LighSwitch Beta 1, deberás desinstalarla antes de instalar la Beta 2.
No obstante, te recomiendo leer el documento "readme" que ha preparado Microsoft acerca de los requerimientos, etc.
Encontrarás este documento en este enlace.
A partir de aquí... ¡manos a la obra!.
.gif)
Desde hace unos días, tenemos ya disponible el Service Pack 1 de Visual Studio 2010.
La descarga tiene un pequeño tamaño de 800 Kb que lanza el programa que se encarga de descargar de Internet el paquete real de instalación que posee un tamaño mucho mayor como es lógico.
El enlace de descarga e información general de Visual Stutio 2010 SP1 lo encontrarás en este enlace.
Si queremos descargar el ISO del SP1, lo podremos hacer en este otro enlace (1.5 Gb).

Desde ayer día 14 de Marzo, es posible instalar IE9 versión final.
Es casi seguro que haya nuevas actualizaciones una vez vayan apareciendo novedades de la W3C con respecto a HTML5, pero de momento, pienso que aquí Microsoft ha hecho lo correcto, y es anticiparse a otros navegadores Web actualizando su producto antes que la competencia, sobre todo porque IE9 ha resultado ser bastante estable desde las primeras versiones beta.
A continuación te indico algunos enlaces de descarga:
IE9 - windows 7 64 bits y Windows Server 2008 R2 64 bits
IE9 - Windows Vista 64 bits y Windows Server 2008 64 bits
IE9 - Windows Vista y Windows Server 2008
Un saludo y bienvenido IE9. :)
.gif)
Microsoft ha sacado a la luz un nuevo paquete de desarrollo y gratuito... hablo de Visual Studio 2010 Express for Windows Phone.
Desde este momento, desarrollar aplicaciones para Windows Phone 7 es mucho más fácil gracias a esta herramienta gratuita.
Los desarrolladores de Visual Studio 2010 podían desde hace tiempo desarrollar aplicaciones para Windows Phone 7, pero ahora gracias a este paquete de desarrollo gratuito de Microsoft, ya no hay excusas.
Podrás acceder a este paquete en este enlace, y a la página de descarga en este otro enlace.
Existe un lanzador de apenas 3.2 Mb que nos permitirá instalar este paquete.
También existe la posibilidad de obtener la imagen iso de instalación (aunque no me ha funcionado bien).
.gif)
Microsoft ha publicado una actualización de su Training Kit sobre Visual Studio 2010 y .NET Framework 4.0.
El paquete de poco más de 410 Mb, contiene recursos de entrenamiento acerca de Visual Studio 2010 y .NET Framework 4.0 incluyendo los cambios y ajustes realizados con el SP1 de Visual Studio 2010.
Es decir, se trata de un paquete totalmente actualizado.
El contenido de este paquete está en inglés y constituido por materiales variados (presentaciones, laboratorios, demostraciones, etc).
Todo ello sobre prácticamente todas las posibles tecnologías (lenguajes, WCF, WF, Web, Windows Azure, Windows Phone 7, etc).
Encontrarás este material en este enlace.

Introducción
Ayer día 2 de Marzo, Apple presentó su iPad 2,... el tablet que muchos pasaron a llamar como el verdadero iPad versión 1.0, ha cumplido el dicho de mucho ruido y pocas nueces.
De hecho, ha sido más decepcionante que ilusionante.
El error se llama Steve Jobs
De todos es conocido ya, que Steve Jobs está pasando por unos malos momentos personales.
Igualmente todos sabemos que Apple está culturalmente arraigado de manera excesivamente fuerte al nombre de Steve Jobs.
Microsoft hizo muy bien hace unos años en desligar a Bill Gates de Microsoft, y ya eso está superado, pero el caso de Apple es diferente.
Por esa razón, cuando ayer apareció Steve Jobs en la pantalla, todo el mundo hablaba de él, de cómo se encontraba, de si le veían físicamente mejor o peor, de si transmitía con más o menos fuerza que antes,... pero ¿del iPad 2?.
Entiendo que Apple quisiera ligar la imagen del iPad 2 a Steve Jobs, o que el propio Steve Jobs en persona pidiera salir a la luz pública para mostrar que sigue vivo y luchador como siempre pese a sus problemas de salud, pero eso por contra ha hecho que el interés por el iPad 2 se desvaneciera bastante.
Ojalá el bueno de Steve se recupere de sus problemas.
Las novedades del iPad 2
Lo más destacable es que el iPad 2 es que pese a sus 10", se ha hecho más delgado (un 33% más delgado), y por lo tanto más ligero (un 15% más ligero).
El iPad 2 tiene "por fin" una cámara (bueno, realmente son dos), algo que a todas luces se sabía que iba a incorporar no sólo por las críticas justísimas recibidas por el original iPad, sino porque el propio Steve Jobs prometió hace tiempo que el nuevo iPad incluiría una cámara. De esta manera, incluye una cámara frontal y otra trasera. No está mal.
Pero por encima de todas las novedades, destacaré el corazón del iPad 2, que ahora contiene un nuevo procesador, el A5, dotado de doble núcleo a 1GHz.
Sobre la batería, sin novedades destacables. Lo cierto es que con las casi 10 horas de vida es suficiente.
También se indica que el procesador gráfico es hasta nueve veces más potente que el procesador gráfico de la original iPad, algo que habrá que evaluar con cierta cautela, ya que aunque me parezca posible, me parece sinceramente demasiado.
Otra novedad interesante es que la nueva iPad montará una nueva versión del sistema operativo de Apple para las tabletas, hablo de iOS 4.3 y que contendrá nuevas utilidades todas ellas muy interesantes (FaceTime para videoconferencia, PhotoBooth para fotografías, etc).
Tampoco quiero dejar de comentar que el nuevo iPad puede ser conectado al televisor con una salida de video Full HD, eso sí con un adaptador que deberemos adquirir aparte.
También han añadido una "pijada" que reconozco que me gusta, el smart cover, que permite envolver la iPad, levantarla apoyándose lateralmente o frontalmente en ella, etc.
El resto de características son las mismas que el original iPad.
Puedes acceder a las características técnicas del iPad 2 en este enlace oficial.
Precio del iPad 2
El precio no ha sufrido alteración.
Esto quiere decir que el iPad 1 bajará de precio casi con total seguridad (hay que quitarse el stock como sea), mientras que el iPad 2 toma el precio de la iPad 1.
Sin dudas una buena noticia.
Disponibilidad del iPad 2
Para dentro de una semana (11 de Marzo) estará disponible en USA, y para la última semana de Marzo en Europa.
Los colores de la iPad 2 serán dos, negro o blanco.
Para más información, accede al enlace oficial de Apple - iPad..

Introducción
El equipo de Microsoft Visual Studio, publicó hace ya bastante tiempo unas herramientas de productividad que a mí me parecen fantásticas.
Desde que las he utilizado me han parecido muy útiles, y me han hecho incluso dependientes de ellas, tanto que cuando llego a un equipo que no las tiene instaladas me pregunto porqué no están instaladas y las hecho rápidamente en falta.
Nueva versión
Estas herramientas que se instalan en Visual Studio 2010 y que pueden ser activadas o desactivadas de forma independiente, poseen diferentes acciones todas ellas muy útiles.
La nueva versión (v10.0.20214.15) agrega algunas mejoras y resuelve algunos pequeños fallos o comportamientos extraños.
Mi sugerencia es que si no las has instalado nunca, que las instales, y que si tienes una versión anterior, que actualices Visual Studio 2010 con esta nueva versión.
Instalación
Podrás descargar las Productivity Power Tools desde el enlace de Microsoft Visual Studio Gallery que encontrarás en este enlace.
En ese mismo enlace, encontrarás información adicional acerca de estas herramientas, características y preguntas y respuestas de los usuarios.

Introducción
Fabuloso revuelo el que se ha montado alrededor de Android 3.0 (Honeycomb) y la posibilidad o no de ejecutar Flash.
El caso es que ha corrido como la pólvora el hecho de que Flash para Android 3.0 no sería incluido en esta nueva versión de Android hasta bien avanzada la primavera.
Los hechos
Muchos somos los que estamos espectantes acerca de la nueva Tablet, la Motorola Xoom.

Tampoco es menos cierto, que en mi caso miro de reojo la inminente aparición de la nueva versión de la Tablet de Apple (la que se denomina como iPad 2).

Pero lo que más me sorprendido es conocer la letra pequeña del Motorola Xoom cuando hablan de Android 3.0, y es que indica que Flash aparecerá en primavera.
Lo más deleznable de este asunto es quizás que Google ha anunciado a bombo y platillo su estupendo Android 3.0 con soporte para Flash, y la archiconocida batalla de steve Jobs contra Adobe y su Flash.
sin embargo, la letra pequeña indica que Android 3.0 no soporta aún Flash.
¿Dónde está el error?.
Explicación del asunto
Apenas aparecer estos rumores, tanto Google como Adobe se apresuraron a tranquilizar a las masas, sobretodo sabiendo que Apple va a contraatacar con su nueva iPad 2.
Según Google y Adobe, el retraso se debe a Adobe que tiene que adecuar Flash para ejecutarse adecuadamente en el nuevo sistema operativo de tabletas de Google (Honeycomb o versión 3.0 si se prefiere).
De esta manera, han anunciado que esta actualización estará disponible el breve, así que los usuarios que quieran adquirir un tablet con Android 3.0, no tendrán que temer nada.
Ahora bien, el mal está hecho, y el mosqueo generalizado del personal también.
Incluso ha habido una multitud de potenciales compradores que han empezado a dudar de Google, ya que es bastante feo ocultar estos detalles sabedores que este tipo de actuaciones es un caballo de batalla bastante manido y más cuando se habla de tecnologías de la información.
¿Qué hacer?
Lógicamente esperar.
Veremos si Flash llega a tiempo para Android 3.0, o si por el bien de Google, no se queda a medias.
Veremos igualmente que novedades esconde el iPad 2 de Apple, y desde la lejanía conoceremos los avances de Microsoft respecto a su Tablet con (presumiblemente) un sistema operativo basado en Windows Phone 7 y quizás unos aderezos de windows 7.
Como podemos observar, el mundo de las "tabletas" está muy movido últimamente. Algo lento en mi opinión, pero pese a todo, bastante ajetreado.
Hoy conoceremos que trae de nuevo el iPad 2 y sabremos a partir de hoy si la gente de Google se pone las pilas buscando ese valor añadido y diferencial con respecto a los productos Apple o no.

Introducción
Google ha anunciado recientemente la versión final de su SDK para Android, hablamos de Android SDK 3.0.
El nuevo nivel de APIs es el 11, y puede ser descargado igualmente para desarrollar aplicaciones Android con MonoDroid como orientaba en la primera entrada de mi blog ayer mismo.
Características de Android SDK 3.0
Si queremos acceder a las características o novedades de Android SDK 3.0, podremos hacerlo haciendo clic en este enlace.
Recordemos que esta nueva versión tiene implicaciones directas con las nuevas Tablet con Android, por lo que en cuanto a cambios con respecto a la interfaz de usuario se refiere, junto a algunas nuevas e interesantes características a tener en cuenta.
Descarga de Android SDK 3.0
Android SDK 3.0 requiere del SDK Tools r10 ó superior.
Las SDK Tools las encontrarás en este enlace.
La descarga del SDK en sus diferentes plataformas (Windows, Mac, Linux) la encontrarás en este otro enlace.
Actualización del plugin de Eclipse
Igualmente, se han publicado actualizaciones del plugin de Eclipse para desarrollar aplicaciones Android con Java y Eclipse.
Para más información sobre todo esto, acceder al blog de Android Developers.

Introducción
Microsoft Visual Studio LightSwitch es un entorno de desarrollo que está cerrando Microsoft (actualmente está en versión Beta) y que nos permite desarrollar aplicaciones Web y de escritorio orientadas a datos con interfaces ricas de forma muy sencilla.
Para explicar mejor como funciona y en qué consiste realmente, he decidido crear una serie de videos en español que hablen de LightSwitch y que han sido publicados en Channel9 Spain por parte de Microsoft Spain.
Videos
1: Toma de contacto con Visual Studio LightSwitch (parte 1) Duración: 12:20. Acceso al video.
2: Toma de contacto con Visual Studio LightSwitch (parte 2) Duración: 12:43. Acceso al video.
3: Toma de contacto con Visual Studio LightSwitch (parte 3) Duración: 22:43. Acceso al video.
4: Campos combinados y relaciones en Visual Studio LightSwitch Duración: 13:43. Acceso al video.
5: Personalización y vista detalle con Visual Studio LightSwitch Duración: 14:16. Acceso al video.
6: Personalización y filtrado de datos dentro de una misma ventana de LightSwitch Duración: 09:01. Acceso al video.
Espero que la información sea de tu interés, y espero igualmente poder hacer algún video más sobre LightSwitch en breve, explicando más características útiles sobre el programa.
No olvides que está en versión beta y que por esa razón, alguna característica podría tener algún comportamiento un tanto extraño, pero para ser una versión beta debo admitir que me ha sorprendido lo bien que funciona.

Introducción
Para el que aún no lo sepa, jQuery es una librería JavaScript que proporciona acciones comunes en nuestras aplicaciones Web dotándolas de una experiencia mucho más rica y provechosa de cara al usuario.
Tal y como dicen en la página principal de jQuery, éste es diseñado para cambiar la forma en la que escribimos JavaScript.
Anotaciones sobre la actualización
Desde el pasado 23 de Febrero, se ha liberado una nueva revisión de jQuery, hablo de la revisión 1.5.1 de la versión 1.5.
En este caso, no hay novedades destacables con respecto a la versión 1.5.
Quizás lo más destacable es la estrecha relación que existe entre el equipo que trabaja con jQuery y el equipo de Internet Explorer, que está empeñado en resolver todos los problemas que pueda deparar jQuery en Internet Explorer 9.
Paquetes y CDN
Ahora bien, vamos al tajo con respecto a jQuery 1.5.1.
jQuery se presenta en dos distribuciones, una minimizada (29 Kb), y otra sin compresión (212 Kb).
La versión minimizada puede ser accedida en este enlace directo: http://code.jquery.com/jquery-1.5.1.min.js.
La versión sin compresión puede ser accedida en este enlace directo: http://code.jquery.com/jquery-1.5.1.js.
Estos enlaces los podemos usar como CDN para ponerlos en nuestras páginas Web y cargar de esa forma jQuery.
Por otro lado, es posible que queramos utilizar los CDN de Microsoft o de Google. Estos son los siguientes:
Microsoft - minimizada: http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.min.js.
Microsoft - sin compresión: http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js.
Microsoft - minimizada: https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js.
Microsoft - sin compresión: https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js.
jQuery 1.5.1 y Visual Studio
Ahora bien, si queremos desarrollar aplicaciones con Visual Studio 2010 y jQuery, y queremos hacer uso del Intellisense, entonces y de momento, tendremos que esperas.
En cuanto apareza esta información, será publicada en la Web de jQuery en este enlace.
Documentación sobre jQuery 1.5.1
Para completar esta entrada, indicaré la documentación de jQuery v1.5.1 que podrás encontrarla en este enlace.
La futura versión jQuery 1.6
Finalmente, comentar que el equipo de jQuery tiene pensado sacar una nueva versión de jQuery (jQuery 1.6) para Abril o Mayo.
Abrirán una discusión acerca de esta nueva versión en IRC (irc.freenode.net) dentro del grupo #jquery-meeting para el próximo 7 de Marzo.
Si tienes propuestas que hacer, nos piden que lo hagamos a través de este formulario.

Introducción
Empezaremos por definir en primer lugar qué es MonoDroid.
MonoDroid es un SDK que nos permitirá desarrollar aplicaciones Software para Android con .NET, concretamente con C# como lenguaje de programación.
En un futuro muy próximo, MonoDroid estará disponiblemente igualmente para desarrolladores de VB.
Si quieres acceder a más preguntas y respuestas sobre MonoDroid, entonces te invito a visitar este enlace (FAQ de MonoDroid).
Actualmente, MonoDroid está en fase Beta, lo que quiere decir que está bajo desarrollo y mejora, por lo tanto, es posible que el entorno pueda causar algún problema (bug) en algún momento dado.
Visual Studio 2010
Podremos trabajar con MonoDroid en Visual Studio 2010 a excepción de Visual Studio 2010 Express Edition.
Dicho esto, cualquier otra versión de Visual Studio 2010 estará habilitada para ejecutar el SDK de MonoDroid y para desarrollar aplicaciones para Android.
Requerimientos para instalar MonoDroid
Para poder ejecutar y trabajar con el SDK de MonoDroid en Visual Studio 2010, deberemos seguir la instalación de la siguiente manera.
1: instalaremos el Java SDK 1.6 [JDK] 32 bits.
Esto lo encontraremos en este enlace.
2: instalaremos el Android Windows SDK de Google.
Encontraremos el SDK en este enlace.
Nota importante: si cuando vas a instalar Android SDK, el instalador te indica que no se ha encontrado el JDK correspondiente e instalado en el punto anterior y deshabilita el botón de avanzar, pulsa el botón de retroceder del instalador, y nuevamente el botón de avanzar. El instalador habrá detectado correctamente el JDK y el botón de avanzar que aparecía deshabilitado aparecerá ahora habilitado.
3: después de instalar el SDK de Android, instalaremos todos los paquetes que consideremos oportuno para el desarrollo de aplicaciones Android desde Visual Studio 2010.
Esta tarea es una tarea automática que lanza el instalador del SDK de Android al final del proceso de instalación.
4: configuraremos a continuación el emulador de Android que será lanzado desde Visual Studio 2010 para probar nuestros desarrollos.
Podemos acceder a la información oficial sobre la configuración para no saltarnos ningún paso.
No es muy complicado seguir los pasos, pero debemos tener cuidado con lo que hacemos porque también tendremos que tener en cuenta los recursos con los que contamos.
Si te pones a jugar un poco con estas opciones, observarás que serás capaz de dejar bastante fundido el emulador.
Como nombre del AVD (Android Virtual Device) te sugiero poner un nombre sin espacios en blanco.
5: para finalizar, instalaremos el plugin para Visual Studio 2010 que nos permitirá desarrollar aplicaciones Android con Visual Studio 2010.
Ni que decir que se sugiere cerrar Visual Studio 2010 antes de comenzar a instalar el plugin, y que la instalación consumirá un tiempo (nada comparable con el Android SDK).
En mi caso, he decidido instalar la versión 1.0.9639 que es la última preview de MonoDroid.
Accederemos a la descarga del plugin en este enlace.
Una vez que tengamos instalado MonoDroid, podremos empezar a desarrollar nuestras aplicaciones Android con .NET y en este caso, con Visual Studio 2010.

Como puedes ver, la operación de preparación e instalación del entorno es realmente sencilla.
Para que sirva de información adicional, tengo MonoDroid en dos máquinas diferentes con Windows 7 y Visual Studio 2010, una de 32 bits y otra de 64 bits, y ambas instalaciones sin problemas.
En breve, espero poder poner algo más de información sobre el desarrollo de aplicaciones de MonoDroid con Visual Studio 2010.