martes, 5 de junio de 2007

El Patrón Estrategia en C#

Vamos a ver ahora como implementar el patrón estrategia en c#.

Vamos a reutilizar las clases que venimos trabajando con el puente y el decorador. Pues esa es la idea de los patrones ¿no?. Vamos a reutilizar, entonces, la interfaz "procesarNombres" y la Clase "Puente" dentro del namespace estrategia.

Vamos a crear la clase de contexto:



using System;

using System.Collections.Generic;

using System.Text;



namespace estrategia

{

public class contexto

{

IProcesarNombres _MiClase;



public IProcesarNombres MiClase

{

get { return _MiClase; }

set { _MiClase = value; }

}



public contexto(IProcesarNombres Clase)

{

MiClase = Clase;

}

}

}
 
Ahora crearemos la estrategia abstracta que implementa IProcesarNombres.
 



using System;

using System.Collections.Generic;

using System.Text;



namespace estrategia

{

public class Estrategia : IProcesarNombres

{

private contexto _contexto;



public contexto Contexto

{

get { return _contexto; }

set { _contexto = value; }

}



public Estrategia(contexto clase)

{

Contexto = clase;

}



public Estrategia()

{

}



public void AsignarContexto(contexto clase)

{

Contexto = clase;

}



public string ProcesarNombres(string Nombre, string Apellido)

{

return Contexto.MiClase.ProcesarNombres(Nombre, Apellido);

}



}

}
 

Ya teniendo el contexto y la estategia abstracta podemos hacer las estrategias concretas que también implementan IProcesarNombres. 
Vamos a utlizar aquí la clase puente que ya implementa esta interfaz y además vamos a crear dos estrategias más: Una que muestre nombre y apellido, y otra que Muestre 'Apellido:' y 'Nombre:' y sus respectivos valores.



using System;

using System.Collections.Generic;

using System.Text;



namespace estrategia

{

public class NombreApellido:IProcesarNombres

{

private String _caracter = " ";



public String Caracter

{

get { return _caracter; }

set { _caracter = value; }

}



public string ProcesarNombres(string Nombre, string Apellido)

{

return Nombre.Trim() + Caracter + Apellido.Trim();

}

}
}





using System;

using System.Collections.Generic;

using System.Text;



namespace estrategia

{

public class Enriquecido:IProcesarNombres

{

private String _caracter = " - ";



public String Caracter

{

get { return _caracter; }

set { _caracter = value; }

}



public string ProcesarNombres(string Nombre, string Apellido)

{

return "Apellido: " + Apellido.Trim() + Caracter + "Nombre: " + Nombre.Trim();

}

}

}
Ahora sólo nos falta ver como deberíamos utilizarlo. En la siguiente figura se muestra el formulario.
 
El código que contiene es el siguiente:



using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using estrategia;



namespace WindowsApplication1

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}



private void btn1_Click(object sender, EventArgs e)

{

Estrategia Proceso = new Estrategia(new contexto(new NombreApellido()));

txt1.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);

}



private void button1_Click(object sender, EventArgs e)

{

Estrategia Proceso = new Estrategia(new contexto(new Puente()));

txt2.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);

}



private void btn3_Click(object sender, EventArgs e)

{

Estrategia Proceso = new Estrategia(new contexto(new Enriquecido()));

txt3.Text = Proceso.ProcesarNombres(txtNombre.Text, txtApellido.Text);

}



}

}
 
Como se puede observar es muy sencillo cambiar de estrategia y obtener un resultado distinto cada vez.

1 comentario:

MarcelCH dijo...

Buen dia Rodrigo,
Tambien se puede hacer lo mismo con Factory Pattern. Cual es la ventaja del 1 respecto al otro.

Por que a la clase Factory le digo pasame la clase Puente o Enriquecido y me entrega el objeto para proceder con mi proceso.