Está en la página 1de 25

Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Patrones de Fabricacin: Fbricas de


Objetos
Por Len Welicki

Contenido
1. Introduccin
1.1. Fbricas
1.2. Factory Method vs. Creation Methods
1.3. Relacin entre los Patrones de Factora
2. Factory Method
2.1. Definicin del Patrn
2.2. Breve Discusin
2.3. Ejemplo "No Software"
2.4. Ejemplos en .net Framework
2.5. Ejemplos de Cdigo
2.5.1. Variaciones de Factory Method
2.5.1.1. Creador es una Clase Abstracta o Interface
2.5.1.2. Creador es una Clase Concreta con Implementacin Predeterminada
2.5.1.3. Mtodos de Fabricacin Parametrizados
2.5.1.4. Lazy Initialization
2.5.1.5. Combinacin de Factory Method y Template Method
3. Abstract Factory
3.1. Definicin del Patrn
3.2. Breve Discusin
3.3. Factory Method y Abstract Factory
3.4. Ejemplo "No Software"
3.5. Ejemplos en .net
3.6. Ejemplo de Cdigo
4. Factory Pattern (Simple Factory)
4.1. Ejemplos de Cdigo
4.2. Por qu estas Clases no se engloban en los Patrones Anteriores?
4.2.1. Simple Factory y Factory Method
4.2.2. Simple Factory y Abstract Factory
5. Conclusin: Flexibilidad y Complejidad
Referencias y Bibliografa

1. Introduccin
En este artculo analizaremos los patrones de fabricacin ms conocidos. Llamamos patrones de fabricacin a
aquellos patrones que involucran algn tipo de factora o fbrica (factory, en ingls) de objetos. Estos
patrones entran en la categora de patrones de creacin [GoF95], la cual comparten con otros patrones tales
como el Singleton, Builder y Prototype [GoF95].

Los objetos de fabricacin (fbricas) tienen la responsabilidad de crear instancias de objetos de otras clases.
Tienen adems la responsabilidad y el conocimiento necesario para encapsular la forma en que se crean
determinados tipos de objetos en una aplicacin.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 1 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Existen diferentes patrones de fabricacin. En este artculo, trataremos Abstract Factory, Factory Method, y
Simple Factory. Los dos primeros estn incluidos en el catlogo del GoF (presentado y analizado en la
entrega anterior) y sern tratados en mayor profundidad.

1.1. Fbricas
Para comenzar con nuestro estudio debemos definir claramente qu es una factora o fbrica. De la misma
forma que sucede con muchos conceptos en la Ingeniera del Software, existen varias definiciones para este
trmino (en la entrega anterior hemos experimentado esta situacin para el concepto de patrn); por tanto,
es fundamental clarificar este concepto para sentar las bases de nuestro estudio posterior.

El trmino factory (o fbrica) adolece de ser sobreutilizado e impreciso. Mucha gente se refiere a factory para
indicar una implementacin de Factory Method o de Abstract Factory (patrones definidos en el libro del
GoF). Otros sin embargo, se refieren a un objeto que crea instancias de otros, aunque no sigue las reglas de
los patrones mencionados anteriormente.

La falta de consenso sobre el trmino dificulta la comunicacin que, como ya hemos visto anteriormente, es
uno de los objetivos de los patrones (poder referirse en forma unvoca a una abstraccin de mayor nivel que
la clase individual, incrementando as el vocabulario de los ingenieros de software). Recordemos entonces una
importante frase de la entrega anterior:

Los Patrones permiten establecer un vocabulario comn de diseo, cambiando el nivel de abstraccin a
colaboraciones entre clases y permitiendo comunicar experiencia sobre dichos problemas y soluciones. Son
tambin un gran mecanismo de comunicacin para transmitir la experiencia de los ingenieros y diseadores
experimentados a los ms nveles, convirtindose en unas de las vas para la gestin del conocimiento.

Por tanto, es muy importante establecer un significado claro para este trmino, a los efectos de construir este
vocabulario comn.

Llamaremos fbrica, factora o factory a una clase que implemente uno o ms mtodos de creacin, que son
los mtodos que se encargan de crear instancias de objetos (estas instancias pueden ser de esta misma clase
o de otras). Esta clase tiene entre sus responsabilidades la creacin de instancias de objetos, pero puede
tener tambin otras responsabilidades adicionales. Los mtodos de creacin pueden ser estticos.

Existen diferentes "tipos" de fbricas. A continuacin enumeraremos cada una de ellos, a los efectos de dejar
bien en claro sus significados:

Simple Factory

Clase utilizada para crear nuevas instancias de objetos.

Factory Method

Define una interfaz para crear objetos pero deja que sean las subclases las que deciden qu clases instanciar.

Abstract Factory

Proporciona una interfaz para crear familias de objetos relacionados o que dependen entre s, sin especificar
sus clases concretas.

En la Figura 1 se muestra los diferentes tipos de factoras con las que trabajaremos en este artculo. En cada
caso, cada cuadro representa una clase y cada lnea es un mtodo en esa clase:

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 2 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 1: Tipos de fbricas, inspirado en [Kerievsky04]. Volver al texto.

A lo largo de este artculo estudiaremos en mayor profundidad cada uno de estos patrones.

1.2 Factory Method vs. Creation Methods


Cmo llamar a un mtodo que crea instancias de otras clases? Muchas veces se lo llama Factory Method,
aunque esto puede prestarse a malos entendidos, dado que puede confundirse con el patrn del GoF
homnimo. Por lo tanto, llamaremos a los mtodos (o funciones) encargadas de crear instancias de otras
clases Creation Methods (mtodos de creacin) a los efectos de establecer claramente esta diferenciacin.

En la Figura 2 se muestra la relacin entre los conceptos Factory Method y Creation Method:

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 3 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 2: Relacin entre Factory Method y Factory Function; Factory Method contiene varios Creation Methods
(mtodos de creacin). Volver al texto.

1.3 Relacin entre los Patrones de Factora


Los patrones no existen aislados el uno del otro, sino ms bien dentro del contexto de un lenguaje o sistema
de patrones. Por consiguiente existen relaciones entre ellos que pueden determinar cundo, cmo y por qu
utilizar uno u otro. Los patrones de fabricacin no estn exentos de esto.

En el libro del GoF por ejemplo, se indica que el patrn Abstract Factory se implementa utilizando Factory
Method. A su vez, ambos patrones estn relacionados con otros patrones del catlogo. En la Figura 3 se
muestran las relaciones entre patrones de creacin que existen dentro del catlogo del GoF [GoF95]:

Figura 3: Relaciones entre los patrones de creacin del catlogo del GoF (tomada de [GoF95]). Hemos
marcado con un borde rojo los patrones que tratamos en este artculo (Abstract Factory y Factory Method).
Volver al texto.

En la Figura 4 se representa la forma en que estn relacionados todos los conceptos referentes a las fbricas
estudiados hasta ahora:

Figura 4: Diagrama basado en UML que muestra las relaciones entre los distintos patrones tratados en este
artculo. Volver al texto.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 4 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

En la vida real, los patrones no estn segregados por lneas absolutas. A menudo, una clase puede utilizar
uno o ms patrones, haciendo difuso el lmite entre ambos. Adicionalmente, se puede comenzar utilizando un
patrn sencillo y evolucionar hacia otro ms complejo en funcin de las necesidades de nuestra aplicacin

Principio de la pgina
2. Factory Method
Factory Method define una interfaz para crear objetos, pero deja que sean las subclases quienes decidan qu
clases instanciar; permite que una clase delegue en sus subclases la creacin de objetos.

2.1 Definicin del Patrn


A continuacin presentaremos una versin reducida de la plantilla de este patrn. Para obtener la versin
completa, consulta el libro del GoF:

Problema

Una clase necesita instanciar otra clase derivada de una tercera clase, pero no sabe cul. Factory Method
permite a la clase derivada tomar esta decisin.

Solucin

Una clase derivada toma la decisin sobre qu clase instanciar y cmo instanciarla (Ver Figura 5):

Figura 5: Diagrama OMT de Factory Method, tomado del libro del GoF. Volver al texto.

Participantes

Producto

Define la interfaz de los objetos que crea el mtodo de fabricacin.

ProductoConcreto

Implementa la interfaz Producto.

Creador

Declara el mtodo de fabricacin, el cual devuelve un objeto del tipo Producto. Tambin puede definir una
implementacin predeterminada del mtodo de fabricacin que devuelve un objeto ProductoConcreto.
Puede llamar al mtodo de fabricacin para crear un objeto Producto.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 5 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

CreadorConcreto

Redefine el mtodo de fabricacin para devolver una instancia de ProductoConcreto.

Aplicabilidad

Usar cuando:

Una clase no puede prever la clase de objetos que debe crear.


Una clase quiere que sean sus subclases quienes especifiquen los objetos que sta crea.
Las clases delegan la responsabilidad en una de entre varias clases auxiliares, y queremos localizar
concretamente en qu subclase de auxiliar se delega.

Consecuencias

Proporciona enganches para las subclases. Crear objetos dentro de una clase con un mtodo de
fabricacin es siempre ms flexible que hacerlo directamente. Conecta jerarquas de clases paralelas.

Resumen 1: Vista simplificada y resumida del patrn Factory Method, tomado de [GoF95] y [DPE01]

2.2 Breve Discusin


El patrn Factory Method permite escribir aplicaciones que son ms flexibles respecto de los tipos a utilizar
difiriendo la creacin de las instancias en el sistema a subclases que pueden ser extendidas a medida que
evoluciona el sistema. Permite tambin encapsular el conocimiento referente a la creacin de objetos. Factory
Method hace tambin que el diseo sea ms adaptable a cambio de slo un poco ms de complejidad. Se
utiliza frecuentemente con Template Method. En la seccin de ejemplos de cdigo de este patrn
presentaremos una implementacin de este caso.

Uno de los principales inconvenientes que puede presentar este patrn es que puede requerir crear una nueva
clase simplemente para cambiar la clase de Producto.

2.3 Ejemplo "No Software"


En [Duell97] se presenta el siguiente ejemplo:

Las prensas de moldeado a inyeccin sirven para explicar este patrn. Los fabricantes de juguetes de plstico
procesan plstico en polvo para moldeado, e inyectan el plstico en moldes con las formas deseadas. La clase
de un juguete (auto, figura, etc.) es determinada por el molde.

En la Figura 6 se muestra un diagrama UML de este ejemplo:

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 6 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 6: Ejemplo del mundo real del patrn Factory Method, tomado de [Duell97]. Volver al texto.

2.4 Ejemplos en .net Framework


En .net podemos encontrar varias implementaciones de este patrn. A modo de ejemplo, hemos tomado una
de ASP .net 1.1, concretamente, la implementacin del gestor de manejadores (handlers).

En la Figura 7 se muestra el diagrama del GoF actualizado con objetos del Framework .net; en este caso los
del ejemplo seleccionado:

Figura 7: Ejemplo de implementacin del patrn Factory Method en ASP .net. Volver al texto.

2.5 Ejemplos de Cdigo


Existe un nmero de variantes para este patrn. En esta seccin enumeraremos y explicaremos las principales
y ofreceremos ejemplos en C# para cada caso.

Para los ejemplos, utilizaremos como clases Producto un modelo de objetos muy sencillo de una tienda de
mascotas. En este caso, Mascota hace las veces del participante Producto; y Perro, Gato y Vbora son
instancias de Producto Concreto (Ver Figura 8):

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 7 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 8: Modelo de objetos Producto utilizados en los ejemplos de implementacin del patrn Factory
Method. Volver al texto.

2.5.1 Variaciones de Factory Method


Si bien existen diversas variaciones en la implementacin de este patrn, los dos principales casos son los
que se indican a continuacin:

Creador es abstracto y no provee una implementacin para el mtodo de creacin que declara.

Creador es una clase concreta y provee una implementacin predeterminada para el mtodo de
creacin que declara.

En las siguientes secciones presentaremos las distintas opciones de implementacin de este patrn y para
cada una de ellas ofreceremos un ejemplo en C#.

2.5.1.1 Creador es una Clase Abstracta o Interfaz


En este caso, el creador es una clase abstracta o interfaz (siempre que sea posible, es ms recomendable
utilizar una interfaz) y no provee una implementacin predeterminada. Por lo tanto, son las clases derivadas
las que tienen la responsabilidad sobre la implementacin de la funcin de creacin.

En el ejemplo que se muestra a continuacin existe un creador que crea instancias de Perro y otro que crea
instancias de Gato, ambos basados en la misma interfaz:

/// <summary>
/// Creador sin implementacin. Puede ser una interfase
/// o una clase abstracta, donde los mtodos de creacin
/// no tienen implementacin
/// </summary>
public interfase ICreador
{
/// <summary>
/// Mtodo de creacin
/// </summary>
/// <returns>Instancia de una mascota</returns>
Mascota Crear();
}

/// <summary>
/// Creador Concreto. Implementa la interfase de creacin
/// </summary>
public class CreadorConcreto: ICreador
{

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 8 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

/// <summary>
/// Mtodo de creacin
/// </summary>
/// <returns>Instancia de una mascota</returns>
public Mascota Crear()
{
return new Perro();
}
}

/// <summary>
/// Otra instancia de Creador Concreto.
/// Implementa la interfase de creacin
/// </summary>
public class OtroCreadorConcreto: ICreador
{
/// <summary>
/// Mtodo de creacin. En este caso, retorna
/// un una instancia de una mascota de la clase Gato
/// </summary>
/// <returns>Instancia de una mascota</returns>
public Mascota Crear()
{
return new Gato();
}
}

Cdigo 1 - Ejemplo de Factory Method donde el Creador es una interfaz. En este ejemplo de cdigo, existen
2 creadores concretos que son las clases que implementan la interfase ICreador. Cada creador crea un
subtipo diferente de Mascota, por ejemplo, Perro en el primer caso y Gato en el segundo.

2.5.1.2 Creador es una Clase Concreta con Implementacin Predeterminada


En este caso, la clase base provee una implementacin predeterminada de la funcin de creacin. Por lo tanto,
las clases hijas pueden re-implementarla o utilizar la implementacin provista por la clase base.

Para lograr este comportamiento, la funcin de creacin en la clase base debe marcarse como virtual (esto
significa que puede ser redefinida por las clases derivadas).

En el ejemplo a continuacin veremos como la clase base crea instancias de objetos de tipo Perro y la
subclase, en cambio, crea instancias de Gato (redefiniendo la implementacin del mtodo de creacin del tipo
base):

/// <summary>
/// Creador. Esta es la clase base del Factory Method.
/// Provee una implementacin default del mtodo de creacin,
/// que puede ser redefinida por los mtodos hijos
/// </summary>
public class Creador
{
/// <summary>
/// Metodo de creacin
/// </summary>

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 9 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

/// <returns>Instancia de una mascota</returns>


public virtual Mascota Crear()
{
return new Perro();
}
}

/// <summary>
/// Creador Concreto. Redefine el mtodo de creacin
/// definido en Creador, cambiando el "ProductoConcreto"
/// que se retorna
/// </summary>
public class CreadorConcreto: Creador
{
/// <summary>
/// Metodo de creacin
/// </summary>
/// <returns>Instancia de una mascota</returns>
public override Mascota Crear()
{
return new Gato();
}
}

Cdigo 2 - Ejemplo de Factory Method donde Creador es una clase concreta y tiene implementacin
predeterminada. Creador provee una implementacin predeterminada que es redefinida por los creadores
concretos. En el ejemplo, CreadorConcreto redefine el mtodo Crear, retornando una instancia de otra
subclase de Mascota (concretamente Gato en lugar de Perro).

2.5.1.3 Mtodos de Fabricacin Parametrizados


Otra variacin del patrn permite que la funcin de creacin cree mltiples instancias de Producto. La
funcin recibe como entrada un parmetro que identifica el tipo de objeto a crear. Todos los objetos creados
por esta funcin deben ser subclases de Producto.

En el ejemplo que se muestra a continuacin, se crea una mascota en funcin de un parmetro con el nombre
del tipo de Mascota. En este mismo ejemplo se crea una subclase de Creador (un creador concreto) muy
quisquilloso: slo puede crear instancias de mascotas de tipo Perro. En los dems casos dispara una
excepcin, explicando el motivo por el cual no ha podido crear la instancia:

/// <summary>
/// Creador. Esta es la clase base del Factory Method.
/// Provee una implementacin default del mtodo de creacin,
/// que puede ser redefinida por los mtodos hijos. El mtodo
/// de creacin acepta parmetros, permitiendo crear diferentes
/// instancias de mascotas
/// </summary>
public class Creador
{
/// <summary>
/// Funcin de creacin de ordenadores. Recibe el tipo
/// de ordenador a crear y retorna una instancia valida
/// </summary>

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 10 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

/// <remarks>
/// Dado que la funcin es virtual, puede ser modificada
/// sus las clases hijas
/// </remarks>
/// <param name="tipo">Tipo de ordenador (producto) a crear</param>
/// <returns>Instancia valida de ordenador (producto)</returns>
public virtual Mascota Crear(string tipo)
{
switch (tipo.ToLower())
{
case "perro":
return new Perro();
case "gato":
return new Gato();
case "vibora":
return new Vibora();
default:
throw new ArgumentException("Tipo de mascota desconocido");
}
}
}

/// <summary>
/// Creador Concreto. Redefine el mtodo de creacin definido en Creador,
/// cambiando el "ProductoConcreto" que se retorna. En este caso,
/// slo permite crear mascotas del tipo "Perro". En los dems casos,
/// dispara una excepcin
/// </summary>
public class CreadorConcreto: CreadorParametrizado
{
/// <summary>
/// Funcin de creacin de ordenadores. Solo permite
/// crear Mascotas de tipo Perro.
/// </summary>
/// <remarks>
/// Esta funcin redefine a la funcin anterior, cambiando
/// el comportamiento de creacin en funcin del mtodo
/// </remarks>
/// <param name="tipo">Tipo de ordenador (producto) a crear</param>
/// <returns>Instancia valida de ordenador (producto)</returns>
public override Mascota Crear(string tipo)
{
switch (tipo.ToLower())
{
case "perro":
return new Perro();
case "gato":
throw new ArgumentException("Soy alrgico a los gatos.");
case "vbora":
throw new ArgumentException("No se puede tener una vbora como mascota.");
default:
throw new ArgumentException("Tipo de mascota desconocido");
}

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 11 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

}
}

Cdigo 3 - Ejemplo de Factory Method con el mtodo de creacin parametrizado. Nota que el mtodo de
creacin adems de recibir un parmetro est marcado como virtual, para poder ser redefinido en las clases
hijas.

2.5.1.4 Lazy Initialization


En algunos casos, por ejemplo cuando la creacin de la instancia tiene un coste elevado, se puede mantener
una referencia a una instancia vlida, la cual slo es creada la primera vez que se solicita. Por lo tanto, slo
incurrimos en el coste de creacin una nica vez. A continuacin se muestra un ejemplo de cmo
implementar esta tcnica:

/// <summary>
/// Creador. Esta es la clase base del patrn Factory Method.
/// Provee una implementacin default del mtodo de creacin,
/// que puede ser redefinida por los mtodos hijos. El mtodo
/// de creacion utiliza Lazy Instantiation.
/// </summary>
public class Creador
{
// instancia de "Producto"
private Mascota producto;

/// <summary>
/// Mtodo de creacin.
/// </summary>
/// <remarks>
/// Es un "TemplateMethod". Para modificar la clase a instanciar,
/// se debe modificar en las clases hijas el mtodo CrearOrdenador
/// </remarks>
/// <returns>Instancia de Mascota</returns>
public Mascota Crear()
{
/// si no se ha creado el producto, lo creamos
if (this.producto == null)
this.CrearMascota();

/// retorna la instancia del producto


return this.producto;
}

/// <summary>
/// Mtodo real de fabricacin.
/// </summary>
/// <remarks>
/// Este mtodo que crea la instancia. Es el que debe ser redefinido
/// en las clases hijas para modificar la clase del objeto a crear
/// </remarks>
protected virtual void CrearMascota()
{
this.producto = new Perro();

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 12 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

}
}

Cdigo 4 - Ejemplo de Factory Method utilizando Lazy Load.

Otro aspecto interesante a notar es la utilizacin del patrn Template Method [GoF95] para seleccionar el
tipo de la instancia a crear. La funcin CrearMascota funciona como Template Method: este mtodo tiene el
comportamiento variable, mientras que crear tiene el comportamiento que no vara. Por lo tanto, si
quisiramos crear una subclase para crear instancias de otro tipo de Mascota (por ejemplo Gato), slo
tendramos que redefinir el mtodo CrearMascota.

2.5.1.5 Combinacin de Factory Method y Template Method


El patrn Template Method "define en una operacin el esqueleto de un algoritmo, delegando en las
subclases algunos de sus pasos. Permite que las subclases redefinan ciertos pasos de un algoritmo sin
cambiar su estructura" [GoF95]. En el ejemplo que se muestra a continuacin mostramos cmo combinar
estos dos patrones.

Para demostrar esto con un ejemplo, implementaremos un cuidador de mascotas. El cuidador tiene la
responsabilidad de alimentar y pasear a nuestras mascotas. Su comportamiento puede describirse de la
siguiente forma:

1. Obtiene una mascota para cuidar.

2. La alimenta.

3. Si tiene 2 ms patas, la lleva a pasear.

Las clases Cuidador y CuidadorDePerros combinan a los patrones Factory Method y Template Method. La
clase Cuidador cumple los roles de Creador en Factory Method y Abstract Class en Template Method.

El mtodo Cuidar tiene el comportamiento fijo y no puede ser redefinido en las clases hijas. Recordando la
definicin del patrn, este mtodo contiene "la estructura del algoritmo". El mtodo abstracto CrearMascota,
en cambio, es un mtodo de creacin (en Factory Method) y una operacin primitiva (en Template Method). En
ambos casos este mtodo debe ser redefinido en las clases derivadas.

La clase CuidadorDePerros muestra un ejemplo de cmo puede crearse un cuidador que sepa tratar con
perros:

/// <summary>
/// Esta es la clase que implementa Template Method
/// y Factory Method. En el caso de Factory Method,
/// hemos implementado la opcin donde el creador
/// es una clase abstracta
/// </summary>
public abstract class Cuidador
{
/// <summary>
/// Este es el template method. Este mtodo es
/// el que tiene la lgica y no se redefine en
/// las clases hijas

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 13 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

/// </summary>
public void Cuidar()
{
/// obtenemos una instancia de una mascota
Mascota mascota = this.CrearMascota();

/// alimentamos a la mascota


mascota.Alimentar();

/// si la mascota tiene mas de 2 patas, la llevamos a pasear


if (mascota.CantidadPatas > 1)
mascota.Pasear();
}

/// <summary>
/// Este es el mtodo de creacin (para el Factory Method)
/// y la Operacin Primitiva que debe ser
/// redefinida por el usuario (para el Template Method)
/// </summary>
/// <returns>Instancia de Mascota</returns>
public abstract Mascota CrearMascota();
}

/// <summary>
/// Creador Concreto. Solo redefine la operacin de creacin, pero hereda
/// el comportamiento fijo de CreadorTemplateMethod
/// </summary>
public class CuidadorDePerro: CreadorTemplateMethod
{
/// <summary>
/// Mtodo de creacin, redefinido de la clase base
/// </summary>
/// <returns>Instancia de Mascota</returns>
public override Mascota CrearMascota()
{
return new Perro();
}
}

Cdigo 5 - Ejemplo de combinacin de Factory Method y Template Method.

Es importante destacar que este cdigo es un ejemplo ilustrativo y por lo tanto puede carecer de sentido en el
mundo real, dado que el cuidador cuida siempre "nuevas instancias de perros". Este ejemplo podra mejorarse
creando una subclase de cuidador que obtenga la instancia de Mascota a partir de una serie de criterios
arbitrarios. Las tcnicas que estamos utilizando permiten probar nuevas alternativas sin afectar al cdigo
existente (por ejemplo, podramos crear una subclase de cuidador, probarla y mejorarla sin necesidad de
modificar a las clases CuidadorDePerros o Cuidador).

Principio de la pgina
3. Abstract Factory
El patrn Abstract Factory proporciona una interfaz para crear familias de objetos relacionados o que
dependen entre s, sin especificar sus clases concretas.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 14 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

3.1 Definicin del Patrn

Intencin

Proporciona una interfaz para crear familias de objetos relacionados o que dependen entre s, sin
especificar sus clases concretas.

Problema

Se necesita instanciar familias de objetos.

Solucin

Coordinar la creacin de familias de objetos. Establecer una forma para quitar las reglas de cmo realizar
la instanciacin fuera del objeto que est usando los objetos a crear. (Ver Figura 9):

Figura 9: Diagrama OMT de Factory Method, tomado del libro del GoF. Volver al texto.

Participantes

FabricaAbstracta

Declara una interfaz para operaciones que crean objetos producto abstractos.

FabricaConcreta

Implementa las operaciones para crear objetos producto concretos.

ProductoAbstracto

Declara una interfaz para un tipo de objeto producto.

ProductoConcreto

Define un objeto producto para que sea creado por la fbrica correspondiente. Implementa la interfase
ProductoAbstracto.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 15 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Cliente

Slo usa interfaces declaradas por las clases FabricaAbstracta y ProductoAbstracto.

Aplicabilidad

Usar cuando:

Un sistema debe ser independiente de cmo se crean, componen y representan sus productos.
Un sistema debe ser configurado con una familia de productos entre varias.
Una familia de objetos producto relacionados est diseada para ser usada conjuntamente y es
necesario hacer cumplir esa restriccin.
Se quiere proporcionar una biblioteca de clases de productos y slo se quiere revelar sus interfaces,
no sus implementaciones.

Consecuencias

Asla las clases concretas.


Facilita el intercambio de familias de productos.
Promueve la consistencia entre productos.
Desventaja: Es difcil dar cabida a nuevos tipos de productos.

Resumen 2 - Vista simplificada y resumida del patrn Abstract Factory, tomado de [GoF95] y [DPE01].

3.2 Breve Discusin


Abstract Factory puede ser utilizado para desarrollar frameworks y sistemas que pueden ser configurados con
una de mltiples familias de productos.

Provee un nivel adicional de indireccin que abstrae la creacin de familias de objetos relacionados o
dependientes sin especificar sus clases concretas. El objeto "fbrica" tiene la responsabilidad de proveer la
funcionalidad y el protocolo para la creacin de la familia completa. Los clientes nunca deben crear objetos
directamente, sino a travs de la factora. Por consiguiente, es fcil cambiar las familias de productos que se
utilizan, porque el tipo especfico de cada instancia aparece slo una vez en la aplicacin: en el mtodo de
creacin donde se crea la instancia.

Como hemos dicho anteriormente, este patrn es utilizado cuando se desean crear familias de productos,
pero... Qu queremos decir con familias de productos? Imaginemos que tenemos una aplicacin y queremos
que pueda mostrarse en mltiples sistemas de ventanas como por ejemplo Windows 9x, 2000, XP, Mac OS y
X-Windows. Cuando creamos los diferentes controles de usuario, es muy importante que se creen en forma
consistente. Por ejemplo, en una ventana no queremos que se mezclen botones tipo Windows 95 con barras
de desplazamiento de estilo MacOS. Por esto, debemos asegurarnos que todos los objetos de interfaz de
usuario que creemos pertenezcan a la misma familia (Windows 95, 2000, XP MacOS, etc.). El patrn Abstract
Factory nos ayuda a resolver este problema.

3.3 Factory Method y Abstract Factory


Abstract Factory generalmente se implementa utilizando Factory Method y por tanto provee al menos toda la
flexibilidad de ste. La diferencia principal entre ambos es que el primero trata con familias de productos,
mientras que el otro se preocupa por un nico producto.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 16 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Abstract Factory se encuentra a un nivel de abstraccin mayor que Factory Method.

Los diseos que usan Abstract Factory son ms flexibles que los que utilizan Factory Method, pero son
tambin ms complejos.

Otra diferencia notable es el mbito de ambos patrones: Factory Method es un patrn de clase, mientras que
Abstract Factory es un patrn de objeto. Los patrones de clase se refieren a las relaciones entre las clases
(estticas, en tiempo de compilacin) y sus subclases mientras que los de objetos tratan sobre relaciones
entre instancias (dinmicas, en tiempo de ejecucin). Los patrones de objetos suelen ser preferibles a los de
clases, ya que se basan en el principio fundamental de usar composicin en lugar de la herencia y en la
delegacin. La mayora de los patrones del GoF tienen mbito de objeto. Para acceder a una discusin ms
detallada sobre este tema, ver [GoF95].

3.4 Ejemplo "No Software"


Este patrn se encuentra en el equipamiento de cuo de metal utilizado en las fbricas de automviles
japonesas. El equipamiento de cuo es un Abstract Factory que crea partes de un automvil. La misma
maquinaria se utiliza para estampar la puerta derecha e izquierda, defensa delantera y trasera, etc., para
diferentes modelos de autos. Mediante el uso de rodillos para cambiar los fines de estampado, las "clases
concretas" producidas por la maquinaria pueden cambiarse en 3 minutos [Duell97].

En la Figura 10, que se muestra a continuacin, vemos un ejemplo de esta situacin (utilizando una notacin
basada en UML):

Figura 10: Ejemplo del mundo real del patrn "Abstract Factory", tomado de . Volver al texto.

3.5 Ejemplos en .net


El patrn Abstract Factory se utiliza en forma intensiva en ADO .net. En la Figura 11 se muestra cmo ha sido
implementado este patrn en los objetos conexin de ADO .net:

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 17 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 11: Implementacin de Abstract Factory en las conexiones ADO .net. Las lneas discontinuas
representan la relacin de creacin (la notacin en este caso es OMT , la misma que se usa en el libro del
GoF). Volver al texto.

En la figura anterior vemos cmo mediante la utilizacin del patrn nos aseguramos que los objetos que se
creen a partir de un tipo de conexin (Transaccin o Command) sean de la misma familia que la del objeto
conexin (SqlClient, OracleClient, etc.)

3.6 Ejemplo de Cdigo


Para mostrar el uso de este patrn, codificaremos en C# el ejemplo que se presenta en la seccin Motivacin
de la plantilla de este patrn en el libro del GoF.

En este caso, se busca que todos los objetos grficos que se creen en una aplicacin que soporte mltiples
sistemas de visualizacin pertenezcan a la misma familia. De este manera, si creamos una ventana para ser
mostrada en Windows, los controles de usuario (scrollbar, textbox, etc) que utilizaremos en ella deben ser
controles para Windows. Lo mismo debera suceder si estuviramos presentando la aplicacin en un Mac.

En la figura Figura 12 se muestra el diagrama OMT del ejemplo:

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 18 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Figura 12: Diagrama OMT del ejemplo de Abstract Factory para regir la creacin de objetos grficos en un
sistema que soporta visualizacin en mltiples sistemas de ventanas. Este diagrama ha sido tomado de la
seccin Motivacin de este patrn en el libro del GoF. Volver al texto.

A continuacin se muestra el cdigo C# para el diagrama anterior:

/// <summary>
/// Abstract Factory. En este caso, la hemos implementado usando
/// una interfase, aunque tambin puede ser una clase abstracta
/// </summary>
public interface IWidgetFactory
{
Window CreateWindow();
Scrollbar CreateScrollbar();
}

/// <summary>
/// Concrete Factory (Fabrica Concreta)
/// </summary>
public class WindowsWidgetFactory: IWidgetFactory
{
public Window CreateWindow()
{
return new WindowsWindow();
}

public Scrollbar CreateScrollbar()


{
return new WindowsScrollbar();
}
}

/// <summary>
/// Concrete Factory (Fabrica Concreta)
/// </summary>

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 19 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

public class MacWidgetFactory: IWidgetFactory


{
public Window CreateWindow()
{
return new MacWindow();
}

public Scrollbar CreateScrollbar()


{
return new MacScrollbar();
}
}

/// <summary>
/// Producto
/// </summary>
public abstract class Window
{
public abstract void Render();
}

/// <summary>
/// Producto
/// </summary>
public abstract class Scrollbar
{
public abstract void Render();
}

/// <summary>
/// Producto Concreto (Scrollbar para Windows)
/// </summary>
public class WindowsScrollbar: Scrollbar
{
public override void Render()
{
Console.WriteLine("Pintando Scrollbar de Windows...");
}
}

/// <summary>
/// Producto Concreto (Ventana para Windows)
/// </summary>
public class WindowsWindow: Window
{
public override void Render()
{
Console.WriteLine("Pintando Ventana de Windows...");
}
}

/// <summary>
/// Producto Concreto (Scrollbar para Mac)

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 20 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

/// </summary>
public class MacScrollbar: Scrollbar
{
public override void Render()
{
Console.WriteLine("Pintando Scrollbar de Mac...");
}
}

/// <summary>
/// Producto Concreto (Ventana para Mac)
/// </summary>
public class MacWindow: Window
{
public override void Render()
{
Console.WriteLine("Pintando Ventana de Mac...");
}
}

class TestClient
{
/// <summary>
/// Punto de entrada principal de la aplicacin.
/// </summary>
[STAThread]
static void Main(string[] args)
{
/// Creo los objetos para windows
IWidgetFactory factory = new WindowsWidgetFactory();
Scrollbar scrollbar = factory.CreateScrollbar();
Window window = factory.CreateWindow();
window.Render();
scrollbar.Render();

/// Ahora, lo mismo pero para Mac.


/// Al cambiar el tipo del factory, todos los objetos que
/// se crean mediante ella son de la misma familia
factory = new MacWidgetFactory();
scrollbar = factory.CreateScrollbar();
window = factory.CreateWindow();
window.Render();
scrollbar.Render();
}
}

Cdigo 6 - Ejemplo de implementacin de Abstract Factory. En el ejemplo hay tambin un cliente de prueba.

Principio de la pgina
4. Factory Pattern (Simple Factory)
Muchas veces, cuando la gente habla de factory pattern, se refiere a uno de los dos patrones que hemos
estudiado anteriormente. Sin embargo, hay casos que no son cubiertos por estos patrones como por ejemplo,

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 21 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

clases con mtodos estticos de fabricacin o fbricas concretas que tienen implementacin, pero sus
mtodos no son redefinibles. En estos casos, estamos ante una implementacin del patrn Simple Factory.

Hemos dejado este tipo de factoras para el final, dado que son ms fciles de entender y analizar que los
otros patrones presentados anteriormente en este artculo.

En este caso, estamos ante tipos que tienen la responsabilidad de crear instancias de objetos de otras clases,
pero que no cumplen con las premisas establecidas en los patrones anteriores.

4.1 Ejemplos de Cdigo

/// <summary>
/// Simple Factory
/// Ejemplo con mtodo de creacin esttico
/// </summary>
public class CreadorDePerros
{
public static Mascota Create ()

return new Perro();


}
}
/// <summary>
/// Ejemplo de Simple Factory
/// </summary>
public class CreadorDeGatos
{
public Mascota Create()
{
return new Gato();
}
}

Cdigo 7 - Ejemplo de implementacin de variaciones de Simple Factory. En el primer caso, el mtodo de


creacin es esttico. Nota que no pueden redefinirse los mtodos de fabricacin en ninguna de las dos clases.

4.2 Por qu estas Clases no se engloban en los Patrones Anteriores?


Quizs la primer pregunta que puedes hacerte al ver el Cdigo 7 es: Por qu estas clases no se
corresponden con los patrones anteriores? En este apartado intentaremos explicarlo ...

4.2.1 Simple Factory y Factory Method


Comencemos con Factory Method. Para ello es fundamental recordar la intencin de este patrn: Factory
Method define una interfaz para crear objetos, pero deja que sean las subclases las que decidan qu clases
instanciar. Permite que una clase delegue en sus subclases la creacin de objetos.

En los ejemplos presentados en el Cdigo 7, las clases no exponen una interfaz que pueda ser redefinida por
clases que deriven de sta. Por tanto, no pueden dejar que sean las subclases las que decidan qu clases
instanciar ni delegar en las subclases la creacin de objetos. En ambos casos esto se debe a que el
comportamiento est definido en cada clase y no puede ser redefinido en sus clases derivadas.

4.2.2 Simple Factory y Abstract Factory


Continuemos con Abstract Factory. De la misma forma que en el caso anterior, recordaremos la intencin de
este patrn: Proporciona una interfaz para crear familias de objetos relacionados o que dependen entre s, sin

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 22 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

especificar sus clases concretas.

En los ejemplos presentados en el Cdigo 7, no exponen una interfaz para crear familias de objetos
relacionados, dado que solo crean un nico producto y tampoco pueden ser redefinidos por las clases
derivadas.

Respecto a la restriccin de las familias, podras estar pensando como contra-argumento el siguiente ejemplo
de cdigo:

/// <summary>
/// Ejemplo de Simple Factory
/// </summary>
public class Creador
{
public static IWindow CreateWindow()
{
return new WindowsWindow();
}

public static IScrollbar CreateScrollbar()


{
return new WindowsScrollbar();
}
}

Cdigo 8 - Ejemplo de implementacin de creacin de familias de productos con Simple Factory.

En este nuevo ejemplo, nuestro creador s crea familias de productos, aunque tiene los siguientes
inconvenientes:

1. No asegura ningn tipo de consistencia.

2. No declara una interfaz de creacin de familias de productos que pueda ser redefinida por las clases
derivadas.

El punto 2 quizs sea el ms fcil de ver, aunque el punto 1 puede generar dudas ... Por eso, discutiremos
brevemente el problema y lo demostraremos con un nuevo bloque de cdigo: al no tener una restriccin
respecto a la interfaz de los creadores de familias, estos pueden mezclarse, produciendo inconsistencias
como las que se muestran en el bloque de cdigo:

/// <summary>
/// Simple Factory para Widgets de Windows
/// </summary>
public class WindowsCreator
{
public static IWindow CreateWindow()
{
return new WindowsWindow();
}

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 23 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

public static IScrollbar CreateScrollbar()


{
return new WindowsScrollbar();
}
}

/// <summary>
/// Simple Factory para Widgets de MAC
/// </summary>
public class MacCreator
{
public static IWindow CreateWindow()
{
return new MacWindow();
}

public static IScrollbar CreateScrollbar()


{
return new MacScrollbar();
}
}

/// <summary>
/// Ejemplo de Simple Factory
/// </summary>
public class ClienteDePruebaConError
{
public void Test()
{
IWindow window = CreadorWindows.CreateWindow();
IScrollbar scrollbar = CreadorMac.CreateScrollbar();
}
}

Cdigo 9 - Ejemplo de inconsistencias al utilizar Simple Factory para crear familias de productos.

En el ejemplo presentado en el Cdigo 9, se crean y combinan elementos de interfaz de usuario de diferentes


familias. En el caso concreto de nuestro ejemplo, estamos creando una ventana de Windows y una Scrollbar
de Mac. Por lo tanto, estamos violando el principio fundamental del patrn, que es proveer una interfaz
consistente para la creacin de familias de productos relacionados. La forma correcta de implementar este
ejemplo utilizando el patrn Abstract Factory ha sido presentada previamente en el bloque de Cdigo 6.

Principio de la pgina
5. Conclusin: Flexibilidad y Complejidad
Los patrones de fabricacin estudiados a lo largo de este artculo aaden flexibilidad a las aplicaciones, pero
a expensas de mayor complejidad. Por lo tanto, es recomendable analizar bien el problema a resolver antes
de incluirlas.

Para terminar, considero oportuno citar la siguiente frase sobre las fbricas de Robert Martin [Martin05]:

No las use por defecto, y no comience utilizndolas frente al primer indicio de que puedan serle tiles ...
Aguarde a tener un problema concreto que las fbricas puedan resolver. Y en ese caso, no dude en utilizarlas.

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 24 de 25
Patrones de Fabricacin: Fbricas de Objetos 20/06/17 21(23

Principio de la pgina
Referencias y Bibliografa
[C204] C2 Wiki: Abstract Factory vs Factory Method.
http://c2.com/cgi/wiki?AbstractFactoryVsFactoryMethod

[Duell97] Duell, Michael: Non-software examples of software design patterns, Object Magazine, July 1997,
pp54.

[Fowler99] Fowler, Martin: Refactoring: Improving the Design of Existing Code, Adisson Wesley, 1999.

[GoF95] Gamma E., Helm, R., Johnson, R., Vlissides J.: Design Patterns: Elements of Reusable Object Oriented
Software, Addison Wesley, 1995.

[Kerievsky04] Kerievsky, Joshua: Refactoring to Patterns, Addison-Wesley, 2004.

[Martin05] Martin, Robert: Principles, Patterns, and Practices: The Factory Pattern.
http://today.java.net/pub/a/today/2005/03/09/factory.html

[PPR04] C2 WikiWikiWeb: Portland Pattern Repository <en lnea>.


http://c2.com/ppr/

[DPE01] Shalloway, Alan; Trott James : Design Patterns Explained : A New perspective on Object Oriented
Design, Pearson Education, 2001.

[Vlissides98] Vlissides, John: Pattern Hatching: Design Patterns Applied, Addison Wesley, 1998.

Len Welicki es Profesor Asociado de Ingeniera Web en el Mster en Ingeniera del Software de la Universidad
Pontificia de Salamanca, Madrid, Espaa; donde actualmente est realizando el Doctorado en Ingeniera
Informtica, su tesis doctoral trata sobre las Arquitecturas de Software y Paradigmas No Convencionales para
Ingeniera Web. Trabaja como Arquitecto de Software. Cuenta con ms de 12 aos de experiencia profesional
en diversas reas de la Ingeniera del Software.

Principio de la pgina

2017 Microsoft

https://msdn.microsoft.com/es-es/library/bb972258(d=printer).aspx Pgina 25 de 25

También podría gustarte