Miguel Matas Blog

Ingeniería y Arquitectura de Software, Proyectos IT, Programación, Personas, Problemas, Mejora Continua, la vida.

Acercándonos al patrón Faí§ade, veamos el patrón Factory

Unos post más atrás (si no recuerdo mal hablando de .NET Remoting) surgió en la conversación el patrón Faí§ade. Es más,incluso se adjuntó un diagrama de arquitectura donde veí­amos implementado el patrón dando vida a la convivencia de servicios web y servicios de remoting en la misma arquitectura.

En su dí­a prometí­ dedicar un post al patrón Faí§ade, pero como este implementa otro patrón llamado Factory, creo que mejor antes vamos a por el Factory para luego atacar Faí§ade con un poco más de base.

El patrón Factory entra en el grupo de patrones de creación (donde también podemos encontrar Singleton del cual ya hemos hablado también en otros post). Los patrones de creación, tal como su nombre indica, se dedica a crear objetos y a encapsular dicha creación para abstraernos de la misma (lo de siempre quitar trabajo, elevar la productividad y la mantenibilidad).

Os dejo aquí­ un PDF interesante al respecto de los patrones de creación por si os interesa el tema a fondo, vienen bastantes ejemplos.

http://www.dei.inf.uc3m.es/docencia/p_s_ciclo/tdp/curso0203/apuntes/factory.pdf

De todas maneras, lo de siempre, yo os voy a dejar una muestra muy pequeña que os sirva de punto de partida y ya luego si os interesa a fondo os metéis a saco teniendo la base ya firme.

Antes de empezar, contaros que hay tres tipos de patrones Factory: Simple Factory, Factory Method y Abstract Factory y aquí­ en principio sólo vamos a hablar de Simple Factory ya que es el patrón que usa Faí§ade, que es a lo que queremos llegar.

Aprovecho y hago un inciso, es importante en esta profesión centrarse en el problema y no irse por las ramas, si sabéis que algo soluciona vuestro problema, a por ello, no os pongáis a mirar y mirar y mirar, porque el tiempo se os va a ir y la fecha de entrega de un proyecto suele ser fija 🙂 Fin del inciso.

Factorí­a Simple + Strategy (mira tíº por donde nos aparece otro patrón)

Allí­ va un ejemplo, a ver si quedan las cosas claras.

Primero una interfaz Vehí­culo (código C#):

public interface Vehiculo
{
 public void Arrancar();
 public void Frenar();
 public void GirarIzquierda();
 public void GirarDerecha();
}

Como véis la interfaz vehí­culo lo que hace es definir una serie de comportamientos comunes a cualquier vehí­culo.

Ahora implementemos dos vehí­culos.

public class Coche : Vehiculo
{
 public void Arrancar()
 {
  // Código necesario para arrancar el coche.
 }

 … Resto de métodos de Vehí­culo …
}

public class Moto : Vehiculo
{
 public void Arrancar()
 {
  // Código necesario para arrancar la moto
  // que no es igual al del coche claro
 }

 … Resto de métodos de Vehí­culo …
}

Como véis lo íºnico que hemos hecho aquí­ es implementar los métodos de un vehí­culo para un coche y una moto. Hemos definido cómo actíºan cada uno por separado. Hemos encapsulado dicho comportamiento en las clases que heredan de vehí­culo.

Y ahora ya “la magia”, la factorí­a que genera vehí­culos:

public class FactoriaVehiculo
{
 public static Vehiculo GetVehiculo (TipoEnumeradoVehiculo vehiculo)
 {
  switch (TipoEnumeradoVehiculo)
  {
   case vehiculo.Coche:
    return new Coche();
    break;
   case vehiculo.Moto:
    return new Moto();
    break;
   default:
    return null;
    break;
  }
 }
}

Hemos utilizado un Tipo Enumerado auxiliar para hacer esto más legible y sobre todo más encapsulado. Otra opción era pasarle a GetVehí­culo un String… pero claro, estamos en lo de siempre, si le pasamos un string estamos dando por hecho que sabemos que hace por dentro la factorí­a, cuando no tiene por qué ser así­.

Bien, por íºltimo, vamos a crear un procedimiento que utilice la factorí­a, para así­ acabar de darle forma al asunto:

public void EjemploFactoria()
{
 // lista genérica, SIEMPRE QUE SEA POSIBLE
 List<Vehiculo> listaVehiculos = new List<Vehiculo>;
 
 // añadimos vehí­culos a la lista genérica
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.Coche));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.Moto));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.MotoConSidecar));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.TodoTerreno));

 // recorremos la lista de vehí­culos
 foreach (Vehiculo unVehiculo in listaVehiculos)
 {
  unVehiculo.Arrancar();
 }

}

¿Queda claro? La factorí­a ha ocultado cómo se crean las clases y las ha devuelto ya generadas. Por cierto, hemos hablado antes del patrón Strategy… ¿pero dónde aparece? Pues lo vemos en funcionamiento en la lí­nea unVehiculo.Arrancar(). Cada vehí­culo arrancará como tenga definido, esa es su estrategia. Strategy es un patrón muy simple y que seguramente habréis implementado muchas veces pero sin haberlo llamado nunca así­ 🙂 Os dejo el link de la wikipedia al respecto aquí­ para que le echéis un ojo.

Por cierto, menudo ejemplo de polimorfismo nos ha salido también, ¿no? Ahora que caigo, ¿podrí­amos definir el polimorfismo como sinónimo de patrón strategy? Tengo que investigarlo.

Más cosas también para terminar, en otros posts también se habló de crear factorí­as de DAO’s, ¿se ve ahora un poco mejor el tema?

¡Saludos a todos y feliz navidad!

Miguel.

9 comments

9 Comments so far

  1. Roberto June 2nd, 2008 6:37 am

    Hola!
    Interesante el post. Creo que hay un error, que por lo menos, a mi me hizo darle una vuelta, pero solo es un detalle. Es la siguiente linea

    listaVehiculos.add(FactoriaVehiculo.GetJuego((TipoEnumeradoVehiculo.Coche));

    creo que deberias reemplazarla por esta.
    listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.Coche));

    Saludos!
    Roberto

  2. Miguel June 2nd, 2008 2:30 pm

    Efectivamente Roberto, tienes toda la razón, deberí­a poner GetVehiculo.

    Lo actualizo.

    Muchas gracias.

    Miguel.

  3. C June 3rd, 2008 2:10 pm

    “Somos ingenieros y nos gusta aprender, pero no nos podemos pasar el dí­a aprendiendo sin dar un resultado porque si no no serí­amos ingenieros, serí­amos cientí­ficos”. Eso ofende, ¿sabes? No sé de dónde sacaste que los cientí­ficos no producimos resultados, pero serí­a agradable que investigaras un poco y vieras que muchos adelantos no fueron por accidente o por la inteligente intervención de las amas de casa.

  4. Miguel June 3rd, 2008 2:50 pm

    C, tienes toda la razón del mundo, no ha sido una afirmación demasiado acertada por mi parte.

    La afirmación viene del dicho que “La diferencia entre un ingeniero y un cientí­fico es que un ingeniero aprende para trabajar y un cientí­fico trabaja para aprender”, afirmación que, claro está, no he sabido trasladar de forma muy correcta a la forma del post.

    Te agradezco la puntualización.

    Un saludo.

    Miguel.

  5. C June 4th, 2008 9:21 pm

    Creo que debo pedirte disculpas. Ahora que leo lo que dije, tengo la impresión de que fui un poco beligerante. Roberto me explicó qué querí­a decir y te diré lo mismo: los cientí­ficos amamos tanto el camino para descubrir algo, como el descubrimiento en sí­ mismo. Y tienes razón en que a veces nos detenemos demasiado tiempo a mirar el paisaje. 🙂

  6. Miguel June 6th, 2008 10:21 am

    Gracias por las aportaciones C 🙂

    Un saludo.

    Miguel.

  7. NetEitor October 10th, 2008 9:03 am

    Muy Buenas Miguel.

    El articulo es bueno, deja claro la utilizacion de un patron sin requerir a un esquema UML, que son muy claros pero el codigo es para mi el mejor vehiculo para entender un articulo de este tipo.

    Creo que el patron factory es muy similar al patron fachade, ya que el fachade se encarga de implementar varias interfaces distintas partiendo de una interfaz base, y ser la interfaz base la unica visible para el cliente, abstrayendole de la complejidad de la implementacion de las interfaces heredadas de la base.

    Solo me surge una curiosidad si existen 3 metodos que hacen lo mismo en distintas clases que heredan de la base. ¿como hacemos para no duplicar el codigo?

    Gracias por aportar tus conocimientos a la sociedad.

  8. Juan Carlos April 2nd, 2009 1:53 pm

    Soy Ingeniero Informatico y llevaba bastante tiempo detras de un site que se basara en patrones de diseño con ejemplos claros y concisos. Solo queria darte las gracias porque he leido la mayoria y estan de puta madre.

  9. Miguel April 11th, 2009 8:48 am

    Aprovecho para responder tanto a NetEitor como a Juan Carlos.

    NetEitor:

    Si hace exactamente lo mismo para los tres hijos, incorpora el método en la clase padre, así­ no repetirás el código. Otra cosa es que no quieras que un cuarto hijo tenga visibilidad sobre dicho método… ahí­ ya tendrí­as que recurrir a otras soluciones.

    Juan Carlos:

    Gracias a ti, cualquier aportación que quieras hacer al respecto será más que bienvenida.

    Un saludo a los dos.

    Miguel.

Leave a reply

Please copy the string s2OfYE to the field below: