martes, 21 de abril de 2015

Abstract Factory

Abstract Factory


Propósito: Define una interfaz para crear familias de objetos relacionados o dependientes, sin especificar sus clases concretas.

También Conocido Como: Kit.


Motivación: 

  • Ej: un framework para la construcción de interfaces de usuario que permita varios look & feel (ej. Presentation Manager y Motif)
  • El cliente no debe cambiar porque cambie la interfaz de usuario
  • Solución:     
  • Una clase abstracta para cada tipo de widget. Subclases para cada look & feel
  • El cliente trabaja con las clases abstractas, independientemente del look & feel concreto
  • Una clase abstracta WidgetFactory con la interfaz para crear cada tipo de widget. Subclases concretas para cada look & feel
Aplicabilidad:
  • Usa el patrón Abstract factory cuando:
  • Un sistema debe ser independiente de cómo se crean, componen y representan sus productos.
  • Un sistema debe configurarse con una de entre varias familias de productos.
  • Una familia de productos relacionados están hechos para usarse juntos, y se necesita cumplir esa restricción.
  • Se desea ofrecer una biblioteca de clases-producto, revelando sus interfaces pero no sus implementaciones.
Estructura:
Participantes:
  • AbstractFactory (WidgetFactory): define la interfaz para crear objetos producto abstractos.
  • ConcreteFactory (MotifWidgetFactory, PMWidgetFactory): implementa las operaciones para crear objetos producto concretos.
  • AbstractProduct (Window, ScrollBar): 
          Define un objeto producto a crear con la factoría concreta correspondiente
          Implementa la interfaz AbstractProduct
  • Client: sólo usa las interfaces de AbstractFactory y AbstractProduct
Colaboraciones: 
  • Normalmente una única instancia de cada ConcreteFactory es creada en tiempo de ejecución. Esta concrete factory crea productos teniendo una implementación particular. para crear diferentes productos de objetos, los clientes deben usar diferentes concrete factory.
  • AbstractFactory delega la creación de productos a sus subclases ConcreteFactory.
Consecuencias:
  • Aísla al cliente de las clases concretas (implementación)
          Ayuda a controlar la clase de objetos que crea una aplicación.
  • Permite cambiar fácilmente de familia de productos.
  • Promueve la consistencia entre productos (esto es, que una aplicación utilice objetos de una sola familia a la vez).
  • La inclusión de nuevos tipos de producto es difícil.
Implementación:
  • Factorías como Singleton
         Asegura una sola instancia de factoría concreta por familia
  • ¿Cómo crear los productos? 
           Utilizando un factory method por producto

Código de ejemplo:

// factoría abstracta (proporciona una implementación por defecto) 
public class MazeFactory  { 
    Maze makeMaze () { return new Maze(); } 
    Wall makeWall () { return new Wall(); } 
    Room makeRoom (int n) { return new Room(n); }
    Door makeDoor (Room r1, Room r2) { return new Door(r1, r2); } 
public class MazeGame   { 
  // @param MazeFactory factory: factoría a usar para la creación de componentes 
    Maze createMaze (MazeFactory factory) { 
          Maze aMaze = factory.makeMaze(); 
          Room r1 = factory.makeRoom(1), r2 = factory.makeRoom(2); 
          Door aDoor = factory.makeDoor(r1, r2); 
          aMaze.addRoom(r1); 
          aMaze.addRoom(r2); 
          r1.setSide(Direction.NORTH, factory.makeWall()); 
          r1.setSide(Direction.EAST, aDoor); 
          r1.setSide(Direction.SOUTH, factory.makeWall());
          r1.setSide(Direction.WEST, factory.makeWall()); 
          r2.setSide(Direction.NORTH, factory.makeWall()); 
          r2.setSide(Direction.EAST, factory.makeWall());
          r2.setSide(Direction.SOUTH, factory.makeWall()); 
          r2.setSide(Direction.WEST, aDoor); 
          return aMaze; 
}}

// factorías concretas (sobrescriben métodos de la factoría abstracta)

public class BombedMazeFactory extends MazeFactory {
      Wall makeWall () { return new BombedWall(); }
      Room makeRoom (int n) { return new RoomWithABomb(n); }
}

public class EnchantedMazeFactory extends MazeFactory {
     Room makeRoom (int n) { return new EnchantedRoom(n, castSpell());}
     Door makeDoor (Room r1, Room r2) {return new DoorNeedingSpell(r1, r2);}
     protected Spell castSpell() { }
}

// cliente

public class MazeTest {
    public static void main (String args[]) {
         MazeGame game = new MazeGame();
         MazeFactory factory = new BombedMazeFactory();
        game.createMaze(factory);
Usos conocidos:

  • ET++ usa Abstract Factory para archivar portablemente sobre diferentes sistemas windows (X Windows y SunView)
  • La clase base abstracta de WindowsSystem define la interfaz para crear objetos que representan recursos del sistema windows.
Patrones relacionados:
  • Se pueden implementar con Factory Method o Prototype.
  • Las factorías concretas suelen ser Singleton.

No hay comentarios:

Publicar un comentario