Número 53 • noviembre 2008

Visual Basic•C#•ASP.NET•ADO.NET•AJAXSilverlight.NET Framework

dotNetManía

Revista dedicada a los profesionales de la plataforma .NET

Menú

Inicio

Números publicados

Libros

Próximo número (nº54)

Autores

¿Qué es dotNetManía?

Garantía de satisfacción

Contactar

Envíenos su feedback

Pedidos

Suscripciones

Renovaciones

Libros

Publicidad


SP1 de Visual Studio 2008

Patrocinadores

Patrocinador Oro
Microsoft

Patrocinador Plata
Alhambra-Eidos

Patrocinadores Bronce
ABOX
Domitienda
Krasis
Plain Concepts
Raona
Solid Quality Mentors

 

 

 

Nº 4 Mayo 2004 Introducción a los Patrones .NET: Observer Material de apoyo

Por Liborio López
 

Creo que no he diseñado menos de 15 capas de acceso a datos a lo largo de mi vida. Y al menos la mitad de las veces, pensaba que eran soluciones inteligentes. Aunque la verdad es que, mirándolo en perspectiva, me replanteo la utilidad de tantas horas, “invertidas”, partiendo de cero en la búsqueda de estas soluciones, además de los problemas que algunas de ellas mostraron, en cuanto a flexibilidad, cuando cambiaba el diseño de la aplicación; por ejemplo, cuando aparece otro cliente con una base de datos distinta a la que utilizaste en el diseño; o cuando la aplicación, inicialmente diseñada para un cliente Windows, se desea convertir a interfaz Web...


 Sin duda, gracias a su integración en el Framework, el patrón observer es el más utilizado de los patrones clásicos, cuando trabajamos en .NET. Siempre que nos subscribimos a un evento, estamos implementando un observer, aunque no nos demos cuenta. Al principio, puede parecer más engorroso implementar el patrón utilizando la infraestructura de delegados. Pero no debemos olvidar que, cuando desarrollamos nuestras aplicaciones, estamos “extendiendo” el Framework, por tanto, deberíamos habituarnos a su forma de trabajar y a sus estilos.

Bibliografía

Design patterns: elements of reusable object-oriented software

 

Editorial: Addison Wesley

Autores: Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides

ISBN: 0-201-63361-2

Páginas: 416

Publicación: Octubre/1994
 

 

Patterns of Enterprise Application Architecture

 

Editorial: Addison Wesley

Autor: Martin Fowler

ISBN: 0-321-12742-0

Páginas:  560

Publicación: Noviembre/2002

 

 


Código fuente

// clase Subject que gestiona una lista de dispositivos

public class GestorMensajes

{

   public GestorMensajes(){

       m_dispositivos = new ArrayList();

   }

 

   // lista de dispositivos subscritos

   private ArrayList m_dispositivos;

 

   // Subscribir dispositivos al gestor de mensajes

   public void Attach(IDispositivo disp){

       m_dispositivos.Add(disp);

   }

 

   // Cancela la subscripción de un dispositivo

   public void Dettach(IDispositivo disp){

       m_dispositivos.Remove(disp);

   }

 

   // boadcasting del mensaje a todos los disp subscritos

   public void SendMessage(string usuario, string texto){

       DatosMensaje msg = new DatosMensaje(usuario, texto);

       foreach (IDispositivo disp in m_dispositivos){

             disp.SendMessage(msg);

       }

   }

}

 

// interfaz que implementan todos los concrete observers

public interface IDispositivo     {

   void SendMessage(DatosMensaje msg);

}

 

// observer que lanza mensaje a consola

public class Consola : IDispositivo     {

   public void SendMessage(DatosMensaje msg){

       Console.WriteLine("{0}: {1}", msg.Usuario, msg.Mensaje );

   }

}

 

// observer que lanza mensaje a fichero

public class Fichero : IDispositivo{

 

   private string m_nombreFichero;

 

   public Fichero(string nombre){

       m_nombreFichero = nombre;

   }

 

   public void SendMessage(DatosMensaje msg){

       StreamWriter writer = new StreamWriter(m_nombreFichero, true);

       writer.WriteLine("{0}: {1}", msg.Usuario, msg.Mensaje);

       writer.Close();

   }

}

 

// clase que contiene el Main

class Class1

{

   // Prueba el sistema de mensajes

   static void Main(string[] args)

   {

       GestorMensajes gestor = new GestorMensajes();

       IDispositivo disp1 = new Consola();

       IDispositivo disp2 = new Fichero("fich1.txt");

       IDispositivo disp3 = new Fichero("fich2.txt");

 

       gestor.Attach(disp1);

       // se envía un mensaje a la consola

       gestor.SendMessage("usu1", "mensaje 1");

       gestor.Attach(disp2);

       // se envía un mensaje a la consola y fich1.txt

       gestor.SendMessage("usu1", "mensaje 2");

       gestor.Attach(disp3);

       // se envía a cosola, fich1.txt y fich2.txt

       gestor.SendMessage("usu1", "mensaje 3");

       gestor.Dettach(disp1);

       // se envía a fich1.txt y fich2.txt

       gestor.SendMessage("usu1", "mensaje 4");

 

   }

}

Fuente 1

 

// clase que hereda de MulticastDelegate

public delegate void MensajeriaEventHandler(object sender, MensajeriaEventArgs args);

 

// Tipo del segundo parámetro del Invoke del delegado

public class MensajeriaEventArgs : EventArgs{

       // nombre del usuario que lanza el mensaje

       private string m_usuario;

       // mensaje

       private string m_mensaje;

 

       MensajeriaEventArgs(string usuario, string mensaje){

             m_usuario = usuario;

             m_mensaje = mensaje;

       }

 

       public string Usuario {

             get {

                    return m_usuario;

             }

       }

       public string Mensaje {

             get {

                    return m_mensaje;

       }

       }

}

 

// clase Subject

public class GestorMensajes{

       public event MensajeriaEventHandler NuevoMensaje;

}

 

Fuente 2

 

public class GestorMensajes{

       public event MensajeriaEventHandler NuevoMensaje;

 

       // Función que envia el mensaje a todos los observers

       public void Notify(object sender, string usuario, string mensaje){

             // comprobamos si hay alguien subscrito

             if (NuevoMensaje != null){

                MensajeriaEventArgs args=new MensajeriaEventArgs(usuario,mensaje);

                // lanzamos el evento para que llame a su

                // lista de invocación

                NuevoMensaje(sender, args);

             }

       }

}

 

// observer que lanza mensaje a consola

public class Consola{

       public void SendMessage(object sender, MensajeriaEventArgs e){

             Console.WriteLine("{0}: {1}", e.Usuario, e.Mensaje );

       }

}

 

// observer que lanza mensaje a fichero

public class Fichero {

 

       private string m_nombreFichero;

 

       public Fichero(string nombre){

             m_nombreFichero = nombre;

       }

 

       public void SendMessage(object sender, MensajeriaEventArgs e){

             StreamWriter writer = new StreamWriter(m_nombreFichero, true);

             writer.WriteLine("{0}: {1}",e.Usuario,e.Mensaje );

             writer.Close();

       }

}

 

class Class1

{

       static void Main(string[] args)

       {

             GestorMensajes  gestor = new GestorMensajes();

             Consola disp1 = new Consola();

             Fichero disp2 = new Fichero("fich1.txt");

             Fichero disp3 = new Fichero("fich2.txt");

 

             gestor.NuevoMensaje += new MensajeriaEventHandler(disp1.SendMessage);

             // se envía un mensaje a la consola

             gestor.Notify(null, "usu1","mensaje 1");

             gestor.NuevoMensaje += new MensajeriaEventHandler(disp2.SendMessage);

             // se envía un mensaje a la consola y fich1.txt

             gestor.Notify(null, "usu1","mensaje 2");

             gestor.NuevoMensaje += new MensajeriaEventHandler(disp3.SendMessage);

             // se envía a cosola, fich1.txt y fich2.txt

             gestor.Notify(null, "usu1","mensaje 3");

             gestor.NuevoMensaje -= new MensajeriaEventHandler(disp1.SendMessage);

             // se envía a fich1.txt y fich2.txt

             gestor.Notify(null, "usu1", "mensaje 4");

       }

}

Fuente 3

 

Volver
 

 

dotNetManía es una revista editada por Netalia. Más información.