DoNet.QueIdeas

Etiqueta: Patrones

Patrón Factoría (Factory)

por José Jorge Márquez Gómez a ago.27, 2010, bajo General, Medio

Un patrón factoría nos sirve para canalizar todas las creaciones de objetos en un solo punto. Esto es útil para un diseño robusto de nuestro sistema y ágil al cambio.

El patrón factoría se puede combinar con el patrón singleton ya que es más cómodo su uso y útil su forma de usar. En este ejemplo pondremos un factoría sin singleton.

Decir que el patrón factoría es del tipo patrones creacionales, que este tipo de patrón abstrae la forma de crear objetos concretos, dando así un soporte para crear objetos de forma abstracta.

Para empezar un patrón factoría debe cumplir:
- Una función o método el cual se encarga de crear objetos de un tipo dado.
- No es obligatorio pero si recomendable que dicha función o método devuelva una abstracción (interfaz o clase abstracta).

Imaginemos que una tienda de pizzas requiere de un software que necesita que tengan una serie de productos (pizzas variadas). Como buenos diseñadores que somos, la creación de objetos de pizzas se podrá hacer desde cualquier parte el proyecto, pero el problema es que hay muchos tipos de pizzas. El crear cada pizza de cada tipo en distintos puntos del programa sería lo primero que pensaríamos, pero… ¿si en vez de eso usamos sentido común y aplicamos el factoría?, esto nos permitiría que dado un nuevo producto o un cambio en alguno de ellos, que solo cambiemos en un solo lugar, teniendo más controlado dicho código. Incluso si os dais cuenta la agilidad al cambio es mucho mayor que ir cambiando todas las posibles apariciones de nuestras pizzas por el código.
Pues bien, el factoría se encargaría de crear todo tipo de pizzas y las ofrecería a todos los posibles puntos del programa.

Nuestro ejemplo sería el siguiente:

- La interfaz IPizza:

    interface IPizza
    {
        void quienSoy();
    }

- Las pizzas concretas:

    public class PizzaBarbacoa: IPizza
    {
        #region Miembros de IPizza

        public void quienSoy()
        {
            Console.WriteLine("Soy una pizza de Barbacoa");
        }

        #endregion
    }
    public class PizzaMargarita: IPizza
    {
        #region Miembros de IPizza

        public void quienSoy()
        {
            Console.WriteLine("Soy una pizza de Margarita");
        }

        #endregion
    }
    public class PizzaPepperoni: IPizza
    {
        #region Miembros de IPizza

        public void quienSoy()
        {
            Console.WriteLine("Soy una pizza de Pepperoni");
        }

        #endregion
    }

- La factoría en cuestión:

    public class PizzaFactory
    {
        public enum tipoPizza
        {
            Pepperoni,Margarita,Barbacoa
        }

        public IPizza getPizza(tipoPizza tipo)
        {
            switch (tipo)
            {
                case tipoPizza.Barbacoa:
                    return new PizzaBarbacoa();
                    break;
                case tipoPizza.Margarita:
                    return new PizzaMargarita();
                    break;
                case tipoPizza.Pepperoni:
                    return new PizzaPepperoni();
                    break;
                default:
                    return new PizzaBarbacoa();
            }
        }
    }

- Un pequeño test:

    public class Test
    {
        public void testPizza()
        {
            //ejemplo no usando factoría
            IPizza pizza1 = new PizzaBarbacoa();
            pizza1.quienSoy();
            IPizza pizza2 = new PizzaMargarita();
            pizza2.quienSoy();
            IPizza pizza3 = new PizzaPepperoni();
            pizza3.quienSoy();
            IPizza pizza4 = new PizzaBarbacoa();
            pizza4.quienSoy();
            IPizza pizza5 = new PizzaMargarita();
            pizza5.quienSoy();

            //ejemplo usando factoría
            PizzaFactory factory = new PizzaFactory();
            IPizza pizza6 = factory.getPizza(PizzaFactory.tipoPizza.Barbacoa);
            pizza6.quienSoy();
            IPizza pizza7 = factory.getPizza(PizzaFactory.tipoPizza.Margarita);
            pizza7.quienSoy();
            IPizza pizza8 = factory.getPizza(PizzaFactory.tipoPizza.Pepperoni);
            pizza8.quienSoy();
        }
    }

Como veis la forma de uso y sus ventajas son mejores. Espero que os sirva!!. Hasta luego!

Deja un comentario :, , , más...

Patrones de diseño Singular (Singleton) y Decorador (Abstract o Decorator) en .NET

por José Jorge Márquez Gómez a nov.24, 2009, bajo General, Medio

Bueno, después de mi letargo (siento mucho no postear antes, pero la universidad me tenia tiene agobiado), voy a hablar de algunos patrones de diseño sobre .NET.

Pero antes un poco de “historia”:

Los patrones de diseño sirven para varias cosas, (extraído de wikipedia):
* Proporcionar catálogos de elementos reusables en el diseño de sistemas software.
* Evitar la reiteración en la búsqueda de soluciones a problemas ya conocidos y solucionados anteriormente.
* Formalizar un vocabulario común entre diseñadores.
* Estandarizar el modo en que se realiza el diseño.
* Facilitar el aprendizaje de las nuevas generaciones de diseñadores condensando conocimiento ya existente.

Y como bien dicen en wikipedia no pretenden imponer nada y abusar de los mismos puede ser un error.

Bien veamos algunos patrones en .NET.

Patron Singular (Singleton):
Este patrón nos asegura que solo haya una instancia por clase evitando así consumos excesivos de recursos o accesos inconsistentes. Sus usos pueden ser varios, entre ellos el acceso a configuraciones globales, de logging, etc..
El esquema general sería:

Public Class PatronSingular
 Private Shared instanciaUnica As PatronSingular

 Private Sub New()
 'constructor privado para generar la instancia la propia clase
 End Sub

 Public Shared Function getInstance() As PatronSingular
 'controlamos la creacion de objetos desde la propia clase.
 If instanciaUnica Is Nothing Then
 instanciaUnica = New PatronSingular()
 End If
 Return instanciaUnica
 End Function
End Class

Un patrón Singleton su constructor debe ser privado para que sea la clase la controle su propia creación y sea responsable de la misma. Debemos crear un método, que normalmente se llama “getInstance()” que nos devuelve dicha instancia de clase para su uso.

Patrón decorador (Decorator):
Nos hace de “envoltura” de objetos, en una definición formal lo que hace es definir una funcionalidad a los objetos que se hereden de este y asignarles así una responsabilidad. En resumen, nos da la posibilidad de generar clases con funciones que se generen dinámicamente. Hay muchos ejemplos de este tipo en .NET, entre ellos los de manejo de ficheros (FileStream su decorador es Stream). En comparación con JAVA, esto correspondería a las clases abstractas. Ejemplo:

Public MustInherit Class PatronDecorador
 'Ofrece una funcionalidad base para todos sus hijos pero
 'que funcionen de manera distinta:
 'por ejemplo:
 'Chocolate tendrá un precio y una descripción distinta que
 'la mantequilla, pero ambos se pueden derretir!.
 Public MustOverride Function Precio() As Double
 Public MustOverride Function Descripcion() As Double

 Public Function Derretir() As Boolean
 'Derretir
 Return True
 End Function

 'Obliga que sus hijos se deban instanciar de una forma concreta
 Public Sub New(ByVal ModificadorAcceso As String)
 End Sub
End Class

Public Class Chocolate
 Inherits PatronDecorador

 Public Overrides Function Descripcion() As Double
 Return "Chocolate"
 End Function

 Public Overrides Function Precio() As Double
 Return 10.2
 End Function

 Public Sub New(ByVal param As String)
 MyBase.New(param)
 End Sub
End Class

Public Class Mantequilla
 Inherits PatronDecorador

 Public Overrides Function Descripcion() As Double
 Return "Mantequilla"
 End Function

 Public Overrides Function Precio() As Double
 Return 3.6
 End Function

 Public Sub New(ByVal param As String)
 MyBase.New(param)
 End Sub
End Class

Bueno, espero escribir más a menudo, pero el tiempo me tiene ahogado!!,  en otro artículo intentaré describir los patrones estrategia, adaptadores y observadores. Saludos!!!

1 Comentario :, , , , más...

¿Buscas algo?

Utilice el formulario siguiente para buscar en el sitio:

¿Todavía no ha encontrado lo que estás buscando? Deja un comentario o contacta con nosotros para encargarnos.

�Visite nuestros amigos!

Unos sitios muy recomendables...

Archivo

Todas las entradas, cronológicamente...