Vous êtes sur la page 1sur 7

Franco Guidi Polanco

Abstract Factory (Fbrica abstracta -GoF)


Descripcin
Presenta una interfaz para la creacin de familias de productos, de forma tal que el
cliente que las utiliza no requiera conocer las clases concretas que la componen. Esto
fuerza al cliente a crear solamente productos relacionados entre si, a la vez que lo
habilita para la utilizacin de distintas familias de productos.
Ejemplo
Un negocio de venta de equipos musicales efecta demostraciones del uso de sus
distintos productos. Los productos se agrupan en familias segn la tecnologa en la
que se basan, como por ejemplo la familia de equipos que utilizan compact disc (CD),
o la familia de equipos basados en cinta magntica. Independientemente del caso, se
supondr que cada familia est compuesta por un medio en que se registra la msica,
un dispositivo que realiza el registro en el respectivo medio, y otro que la reproduce
(ver Fig x.1).

Grabador

Grabador

CD

Cinta magntica

Reproductor

Reproductor

Fig. x.1
Si estos productos ofrecieran a sus usuarios la misma interfaz, un cliente podra realizar el mismo proceso de prueba de productos en cualquiera de las familias. Por ejemplo, podra registrar una cancin utilizando el dispositivo de grabacin, para luego escucharlo en el dispositivo de reproduccin. Slo deberamos asegurarnos que los productos sean compatibles entre si, esto es, que todos ellos pertenezcan a una misma
familia.
El problema consiste en la definicin de un mecanismo que permita al cliente crear y
utilizar familias completas de productos, sin tener conocimiento de cules son los integrantes concretos de la familia.
Descripcin de la solucin ofrecida por el patrn de diseo
La definicin de interfaces constituye el mecanismo mediante el cual es posible ocultar
la implementacin de una clase en aquellas porciones de cdigo en que son utilizadas.
En consecuencia, la definicin de interfaces comunes para aquellos productos anlogos pertenecientes a diferentes familias, permitir a un mismo cliente realizar operaciones similares sobre artefactos de tecnologas distintas. El problema surge cuando el
cliente debe manejar familias cuyos productos no deben entremezclarse. Por ejemplo,

Franco Guidi Polanco

si se pretende utilizar un grabador de CD el cliente debe instanciarlo junto con un CD y


un reproductor de CD, no con una cinta magntica o un reproductor de DVD. La sola
definicin de interfaces para los productos no garantiza que el cliente se limite a crear
slo productos de una misma familia.
El patrn de diseo Abstract Factory resuelve este problema por medio de la encapsulacin de reglas de instanciacin. sta permite ocultar en una clase fbrica el proceso de instanciacin de un conjunto de productos. Por su parte, la encapsulacin de los
productos tras interfaces comunes permitir al cliente utilizar productos anlogos pertenecientes a familias diferentes.
Los nefitos en el campo de los patrones de diseo suelen cuestionarse la diferencia
entre este patrn y el Factory Method, puesto que ambos presentan una estructura
similar, al encapsular en una clase el proceso de instanciacin de un objeto. La diferencia radica en que, mientras el Factory Method tiene por objetivo diferir hacia una
determinada clase (o subclase) el tipo de producto a instanciar, el patrn Abstract Factory persigue garantizar la creacin de un conjunto de productos relacionados.
La implementacin de este patrn requiere definicin de una interfaz adicional a la de
los productos: la interfaz que implementarn las fbricas encargadas de generarlos, y
que permitir al cliente interactuar con ellas. Esta interfaz proveer los mtodos cuyo
contrato consistir en retornar instancias de cada tipo de producto dentro de una familia. En el caso del ejemplo, la interfaz de las fbricas permitir al cliente solicitar la generacin de instancias de grabador, de medios de registro y de reproductores. De esta
forma, el cliente no deber invocar en caso alguno el constructor de los productos,
quedando absolutamente desligado de la implementacin particular de estos ltimos.
Estructura del patrn de diseo

<<stereotipe>>

Client

<<stereotipe>>

<<stereotipe>>

AbstractFactory

AbstractProduct

{abstract}

{abstract}

+createProduct() : AbstractProduct {abstract}

<<stereotipe>>

ConcreteFactory

<<stereotipe>>
<<instantiates>>
produces

ConcreteProduct
#ConcreteProduct()

+createProduct() : AbstractProduct

Fig. x.2

Franco Guidi Polanco

Aplicacin de patrn de diseo


Esquema

<<Interface>>
DevicesFactory
Client
+ createPlayer() : Player
+ createRecorder() : Recorder
+ createMedia() : Media
<<Interface>>
Media
CD Devices
Fact ory

Tape Devices
Factory
Tape

CD

+ saveOnTape(String sound)
+ readTape() : String

+ writeOnDisk(String sound)
+ readDisk() : String

<<Interface>>
Recorder
+ accept(Media)
+ record()

Tape Recorder

CD Recorder

<<Interface>>
Player
+ ac cept(Media)
+ play()

Tape Player

CD Player

Fig. x.3
Participantes

AbstractFactory (Fbrica Abstracta): interfaz DevicesFactory.


-

ConcreteFactory
(Fbrica
CDDevicesFactory.

classes

TapeDevicesFactory

AbstractProduct: interfaces Media, Recorder y Player.


-

concreta):

Cada una de estas clases Implementa la interfaz de la AbstractFactory (DevicesFactory), especificando las operaciones que crean y retornan objetos correspondientes a productos especficos (ConcreteProduct).

Declara una interfaz para las operaciones que crean y restituyen productos.
En la declaracin de cada mtodo, los productos restituidos son del tipo
AbstractProduct.

Declaran las operaciones que caracterizan a los distintos tipos genricos de


productos.

ConcreteProduct: clases Tape, TapeRecorder, TapePlayer, CD, CDRecorder y


CDPlayer.
-

Definen los productos creados por cada ConcreteFactory.

Franco Guidi Polanco

Client: clase Client.

Utiliza la interfaz de la AbstractFactory (DevicesFactory) para acceder a los


mtodos de la ConcreteFactory correspondiente a una familia de productos.
Utiliza los productos a travs de su interfaz AbstractProduct.

Descripcin del cdigo


En primer lugar, se definen las interfaces de las clases que debern implementar los
productos anlogos pertenecientes a las distintas familias. En el caso de este ejemplo,
Media es la interfaz que implementan los soportes de grabacin. Particularmente esta
interfaz no especifica mtodos, slo acta como una interfaz para marcar su rol. Por
su parte, las interfaces Player y Recorder definen las interfaces de reproductores y
grabadores, especificando los distintos mtodos con los cuales el cliente interactuar
con ellas.
public interface Media { }
public interface Player {
public void accept( Media med );
public void play( );
}
public interface Recorder {
public void accept( Media med );
public void record( String sound );
}

Los productos de las distintas familias implementan las interfaces definidas anteriormente. En el caso de la familia de productos basada en el casete, los productos son
Tape, TapeRecorder y TapePlayer:

public class Tape implements Media {


private String tape= "";

public void saveOnTape( String sound ) {


tape = sound;
}
public String readTape( ) {
return tape;
}
}
public class TapeRecorder implements Recorder {
Tape tapeInside;
public void accept( Media med ) {
tapeInside = (Tape) med;
}
public void record( String sound ) {
if( tapeInside == null )
System.out.println( "Error: Insert a tape." );
else
tapeInside.saveOnTape( sound );
}
}

Franco Guidi Polanco

public class TapePlayer implements Player {


Tape tapeInside;
public void accept( Media med ) {
tapeInside = (Tape) med;
}
public void play( ) {
if( tapeInside == null )
System.out.println( "Error: Insert a tape." );
else
System.out.println( tapeInside.readTape() );
}
}

Por su parte, los productos pertenecientes a la familia del CD son:


public class CD implements Media{
private String track = "";
public void writeOnDisk( String sound ) {
track = sound;
}
public String readDisk( ) {
return track;
}
}
public class CDRecorder implements Recorder {
CD cDInside;
public void accept( Media med ) {
cDInside = (CD) med;
}
public void record( String sound ) {
if( cDInside == null )
System.out.println( "Error: No CD." );
else
cDInside.writeOnDisk( sound );
}
}
public class CDPlayer implements Player {
CD cDInside;
public void accept( Media med ) {
cDInside = (CD) med;
}
public void play( ) {
if( cDInside == null )
System.out.println( "Error: No CD." );
else
System.out.println( cDInside.readDisk() );
}
}

La interfaz DevicesFactory declara los mtodos que utilizar el cliente para interactuar con las fabricas de productos. Ntese que cada mtodo tiene la funcin de crear
un tipo de producto especfico:
public interface DevicesFactory {

Franco Guidi Polanco

public Player createPlayer();


public Recorder createRecorder();
public Media createMedia();
}

Las clases TapeDevicesFactory y CDDevicesFactory corresponden a las fbricas de productos de las diferentes familias. Estas clases corresponden a las ConcreteFactory para la creacin de productos correspondientes a las familias basadas en casete en CD, respectivamente.
public class TapeDevicesFactory implements DevicesFactory {
public Player createPlayer() {
return new TapePlayer();
}
public Recorder createRecorder() {
return new TapeRecorder();
}
public Media createMedia() {
return new Tape();
}
}
public class CDDevicesFactory implements DevicesFactory {
public Player createPlayer() {
return new CDPlayer();
}
public Recorder createRecorder() {
return new CDRecorder();
}
public Media createMedia() {
return new CD();
}
}

La clase Client es la que finalmente solicita la instanciacin de los productos, y los


utiliza. El Client accede tanto a la fbrica de productos, como a los productos mismos a travs de sus interfaces comunes. Esto permite al Client utilizar tanto los productos basados en casete, como aquellos basados en CD (como tambin, cualquier
otra familia que adhiera a las interfaces ya declaradas). El Client de este ejemplo
implementa el mtodo selectTechnology recibe una instancia de fbrica, la cual es
utilizada en el interior del mtodo test para crear los productos y utilizarlos. Se debe
notar que la clase Client crea y utiliza los productos sin tener conocimiento acerca
de qu tipo especfico de producto est usando.
class Client {
DevicesFactory technology;
public void selectTechnology( DevicesFactory df ) {
technology = df;
}
public void test(String song) {
Media
media
= technology.createMedia();
Recorder recorder = technology.createRecorder();
Player
player
= technology.createPlayer();
recorder.accept( media );
System.out.println( "Recording the song : " + song );
recorder.record( song );
System.out.println( "Listening the record:" );

Franco Guidi Polanco

player.accept( media );
player.play();
}
}

Finalmente se presenta la aplicacin que crea una instancia de Client, y le asigna


las distintas fbricas de productos para su utilizacin.
public class AbstractFactoryExample {
public static void main ( String[] arg ) {
Client client = new Client();
System.out.println( **Testing tape devices );
client.selectTechnology( new TapeDevicesFactory() );
client.test( "I wanna hold your hand..." );
System.out.println( **Testing CD devices );
client.selectTechnology( new CDDevicesFactory() );
client.test( "Fly me to the moon..." );
}
}

Observaciones respecto del ejemplo


En este ejemplo se ha querido destacar la necesidad de que el cliente deba crear slo
productos de una misma familia. En particular se debe notar que los mtodos que
ofrece la clase CD y la clase Tape, y que son utilizados por los respectivos grabadores
y reproductores, son distintos. Este hecho, resulta irrelevante al momento de crear los
productos, pues la consistencia de la creacin de objetos es garantizada por la clase
fbrica.
Ejecucin del ejemplo
C:\Patterns\Creational\Abstract Factory\>java AbstractFactoryExample
**Testing tape devices
Recording the song : I wanna hold your hand...
Listening the record:
I wanna hold your hand...
**Testing
Recording
Listening
Fly me to

CD devices
the song : Fly me to the moon...
the record:
the moon...

Observaciones sobre el patrn


Debido a que, tanto la AbstractFactory, como los AbstractProduct de este ejemplo no implementan operaciones, en Java resulta ms adecuado codificarlos como interfaces,
en vez de clases abstractas, como se sugiere en [Gamma].
Otros ejemplos
Una compaa que produce videojuegos est interesada en crear un juego en el cual
el usuario debe escoger un personaje que lo representar a lo largo de una aventura,
junto con ciertas herramientas que ste puede utilizar. Las herramientas dependen del
personaje elegido, sin embargo, el cdigo que regula la operacin es idntico para
cualquier personaje.

Vous aimerez peut-être aussi