factory method edmundo Álvarez jiménez antonio fernández alonso daniel lópez ortega

19
FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

Upload: emiliano-arrendondo

Post on 28-Jan-2016

213 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

FACTORY METHOD

Edmundo Álvarez JiménezAntonio Fernández AlonsoDaniel López Ortega

Page 2: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 2URJC

Propósito:

Definir un interfaz para crear un objeto, pero dejando en manos de las subclases la decisión de qué clase concreta instanciar.

Permite que una clase delegue en sus subclases las instanciaciones.

También se le conoce como Virtual Constructor.

Page 3: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 3URJC

Motivación:

Los frameworks usan clases abstractas para definir y relacionar objetos, siendo a menudo encargados de crearlos.

Consideremos un framework para aplicaciones que puede presentar varios documentos al usuario. Dos abstracciones claves en este framework son las clases Application y Document. Los clientes realizan implementaciones específicas de la aplicación heredando de las clases anteriores, que son abstractas.

Page 4: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 4URJC

La clase Application es responsable de gestionar Documents y los creará cuando se necesiten.

Page 5: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 5URJC

Application no puede predecir la subclase de Document que debe instanciar, lo que crea un dilema:

“El framework debe instanciar clases,

pero sólo conoce clases abstractas que no puede instanciar”.

El patrón Factory Method lo soluciona encapsulando la información de qué subclase Document debe crear, sacando ésta del framework.

CreateDocument es un factory method porque es responsable de “fabricar” un objeto.

Page 6: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 6URJC

Aplicación:

Usamos el patrón factory method cuando:

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

Una clase quiere que sus subclases especifiquen el objeto que ésta crea.

Las clases delegan la responsabilidad a una de entre varias subclases auxiliares, y queremos localizar qué subclase concreta es en la que se delega.

Page 7: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 7URJC

Estructura:

Page 8: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 8URJC

Participantes:

Product (Document): Define la interfaz de objetos que crea el factory method.

ConcreteProduct (MyDocument): Implementa la interfaz Product.

Creator (Application): Declara el factory method que devuelve un objeto de tipo Product. Puede definir una implementación por defecto del factory method que devuelva

un objeto ConcreteProduct. Puede llamar al factory method para crear un objeto Product.

ConcreteCreator (MyApplication): Redefine el factory method para devolver una instancia de un ConcreteProduct.

Page 9: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 9URJC

Colaboraciones:

Creator depende de sus subclases para definir el factory method de manera que éste devuelva una instancia del ConcreteProduct apropiado.

Page 10: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 10URJC

Consecuencias:

Factory method elimina la necesidad de ligar clases específicas de la aplicación a nuestro código.

El código sólo trata con la interfaz de Product y puede trabajar con cualquier ConcreteProduct definido por el usuario.

La desventaja del factory method es que los clientes podrían tener que heredar de Creator sólo para crear un determinado objeto de la clase ConcreteProduct.

Page 11: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 11URJC

Estas son dos consecuencias adicionales del patrón factory method:

Proporciona conexión para las subclases: Crear objetos dentro de una clase con un factory method es

más flexible que hacerlos directamente. Aporta a las subclases una conexión para dar una extensión del objeto.

Conecta jerarquías de clases paralelas:El factory method puede ser llamado por los clientes, en

lugar de por Creator.Esto permite que el factory method pueda relacionar dos

jerarquías de clases paralelas.

Page 12: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 12URJC

Implementación:

Al aplicar el patrón factory method encontramos varias cuestiones: Dos variantes principales:

Cuando la clase Creator es abstracta y no proporciona una implementación para el factory method que declara.

Las subclases definirán una implementación porque no hay un comportamiento predeterminado razonable.

Hay que crear instancias de clases imprevisibles.

Cuando Creator no es abstracta y proporciona una implementación predeterminada del factory method.

El Creator usa el factory method por flexibilidad. Crea objetos en una operación aparte, para que las subclases puedan

redefinir el modo en que son creados. Asegurando poder cambiar la clase de objetos que instancia la clase padre desde las subclases.

Page 13: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 13URJC

Factory Methods Parametrizados:Permiten crear varios tipos de productos, recibiendo un parámetro que

identifica el tipo de objeto a crear.Todos los objetos creados por el método compartirán la interfaz Product.

class Creator{public Product create(ProductId id){

if (id == MINE)return new MyProduct();

if (id == YOURS)return new YourProduct();

// repeat for remaining products...

return null;}

}class MyCreator extends Creator{

public Product create(ProductId id){if (id == MINE)

return new MyProduct();if (id == YOURS)

return new YourProduct();if (id == THEIRS)

return new TheirProduct();

return super.create(id);}

}

Page 14: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 14URJC

Variantes y cuestiones específicas del lenguaje:Lenguajes distintos a Java se prestan a otras variaciones.

Usar plantillas para evitar la herencia:Un problema potencial del factory method es que puede

obligar a heredar sólo para crear los objetos Product apropiados.

Convenios de nominación:Es conveniente usar convenios de nominación para aclarar

que estamos usando un factory method.

Page 15: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 15URJC

public class MazeGame{MazeGame(){};//factory methods:Maze makeMaze(){

return new Maze();}Room makeRoom(int n){

return new Room(n);}Wall makeWall(){

return new Wall();}Door makeDoor(Room r1,Room r2){

return new Door(r1,r2);}Maze createMaze(){...}

}

Código de ejemplo: El problema de CreateMaze es que codifica la clase del laberinto,

las habitaciones, las puertas y las paredes. Usando factory methods permitimos a las subclases elegir estos componentes.

Usamos factory methods en MazeGame para crear los objetos laberinto (maze), habitación (room), pared (wall) y puerta (door):

Page 16: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 16URJC

Cada factory method devuelve un componente del laberinto del tipo proporcionado. MazeGame proporciona implementaciones por defecto que devuelven los tipos más simples de laberintos, habitaciones, paredes y puertas.

Ahora podemos hacer que CreateMaze use estos factory method:

Maze CreateMaze(){Maze aMaze = makeMaze();Room r1 = makeRoom(1);Room r2 = makeRoom(2);Door theDoor = makeDoor(r1, r2);

aMaze.addRoom(r1);aMaze.addRoom(r2);

r1.setSide(Direction.NORTH, makeWall());r1.setSide(Direction.EAST, theDoor);r1.setSide(Direction.SOUTH, makeWall());r1.setSide(Direction.WEST, makeWall());

r2.setSide(Direction.NORTH, makeWall());r2.setSide(Direction.EAST, makeWall());r2.setSide(Direction.SOUTH, makeWall());r2.setSide(Direction.WEST, theDoor);

return aMaze;}

Page 17: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 17URJC

Distintos juegos pueden heredar de MazeGame para especializar partes del laberinto.

Las clases de MazeGame pueden redefinir algunos o todos los factory methods para especificar variaciones en los productos. Por ejemplo, un BombedMazeGame puede redefinir los productos Room y Wall para devolver sus variantes con bomba:

public class BombedMazeGame extends MazeGame{Wall makeWall(){

return new BombedWall();}Room makeRoom(int n){

return new RoomWithABomb(n);}

}

Page 18: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 18URJC

public class EnchantedMazeGame extends MazeGame{Room makeRoom(int n){

return new EnchantedRoom(n, CastSpell());}Door makeDoor(Room r1, Room r2){

return new DoorNeedingSpell(r1, r2);}protected Spell castSpell(){...}

}

Se podría definir una variante EnchantedMazeGame como sigue:

Page 19: FACTORY METHOD Edmundo Álvarez Jiménez Antonio Fernández Alonso Daniel López Ortega

SI - Factory Method 19URJC

Patrones relacionados::

El Abstract Factory suele implementarse con Factory Methods.

Los Factory Method suelen llamarse desde Template Methods.