Descargar

Introducción a los Patrones de Creación de Software (página 3)

Enviado por Pablo Turmero


Partes: 1, 2, 3, 4
edu.red 31 public Laberinto nuevoLaberinto () { Laberinto unLab = crearLaberinto(); Habitacion h1 = crearHabitacion(1); Habitacion h2 = crearHabitacion(2); Puerta unaPuerta = crearPuerta(h1,h2); unLab.addHabitacion(h1); unLab.addHabitacion(h2); h1.setLado(Norte, crearPared() ); h1.setLado(Este, unaPuerta) .. h2.setLado(Oeste, unaPuerta); h2.setLado(Sur, crearPared() ); return unLab; } } Ejemplo: Laberinto

edu.red 32 public class JuegoLaberintoEncantado extends JuegoLaberinto { public Habitacion crearHabitacion(int n) { return new HabitacionEncantada(n); } public Pared crearPared() { return new ParedEncantada(); } public Puerta crearPuerta( Habitacion h1, Habitacion h2) { return new PuertaEncantada(h1, h2); } } Ejemplo: Laberinto

edu.red 33 Prototype (Prototipo) Propósito Especificar los tipos de objetos a crear utilizando una instancia prototípica, y crear nuevas instancias mediante copias del prototipo. Motivación GraphicTool es una clase dentro de un framework de creación de editores gráficos, que crea objetos gráficos, (instancias de subclases de Graphic) y los inserta en un documento, ¿cómo puede hacerlo si no sabe qué objetos gráficos concretos debe crear? Una instancia de GraphicTool es una herramienta de una paleta de herramientas y es inicializada con una instancia de Graphic: instancia prototípica.

edu.red 34 Prototipo Aplicabilidad Cuando un sistema deba ser independiente de cómo sus productos son creados, compuestos y representados y: las clases a instanciar son especificadas en tiempo de ejecución, o para evitar crear una jerarquía de factorías paralela a la de productos, o cuando las instancias de una clase sólo pueden encontrarse en uno de un pequeño grupo de estados, o inicializar un objeto es costoso

edu.red 35 Prototipo Consecuencias Al igual que con Builder y Factory Abstract oculta al cliente las clases producto concretas. Es posible añadir y eliminar productos en tiempo de ejecución: mayor flexibilidad que los anteriores. Reduce la necesidad de crear subclases.

edu.red 36 Prototipo Consecuencias La composición reduce el número de clases que es necesario crear: “Definir nuevas clases sin programar” Definir nuevas clases mediante la creación de instancias de clases existentes. Definir nuevas clases cambiando la estructura. objetos compuestos actúan como clases

edu.red 37 Prototipo Implementación Importante en lenguajes que no soportan el concepto de metaclase, así en Smalltalk o Java es menos importante. Usar un manejador de prototipos que se encarga del mantenimiento de una tabla de prototipos. Implementar la operación clone es lo más complicado. A veces se requiere inicializar el objeto creado mediante copia: prototipo con operaciones “set”

edu.red 38 Ejemplo: Laberinto public class FactoriaPrototipoLaberinto { factoriaPrototipoLaberinto (Laberinto lab, Puerta p, Habitacion h, Pared m); { protoLab = lab; protoPuerta = p; protoHab = h; protoPared = m; }

public Laberinto makeLaberinto() {return (Laberinto)protoLab.clone(); }; public Pared makePared() { return (Pared) protoPared.clone(); }; public Habitacion makeHabitacion (int n) { Habitacion h = (Habitacion) protoHab.clone(); h.initialize(n); return h;} public Puerta makePuerta () (Habitacion h1, Habitacion h2) { Puerta p = (Puerta) protoPuerta.clone(); p.initialize(h1,h2); return p; } }

edu.red 39 JuegoLaberinto juego; FactoriaPrototipoLaberinto laberintoSimple = new FactoriaPrototipoLaberinto (new Laberinto, new Puerta, new Habitacion, new Pared); Laberinto unlab = juego. makeLaberinto(laberintoSimple)

JuegoLaberinto juego; FactoriaPrototipoLaberinto otroLaberinto = new FactoriaPrototipoLaberinto (new Laberinto, new PuertaQueOye, new HabitacionEncantada, new Pared); Laberinto unlab = juego. makeLaberinto (otroLaberinto) Ejemplo: Laberinto

edu.red 40 public class JuegoLaberinto { public Laberinto makeLaberinto (FactoriaPrototipoLaberinto factoria) { Laberinto unLab = factoria.makeLaberinto(); Habitacion h1 = factoria.makeHabitacion(1); Habitacion h2 = factoria.makeHabitacion(2); Puerta unaPuerta = factoria.makePuerta(h1,h2); unLab.addHabitacion(h1); unLab.addHabitacion(h2); h1.setLado(Norte, factoria.makePared() ); h1.setLado(Este, unaPuerta) .. h2.setLado(Oeste, unaPuerta); h2.setLado(Sur, factoria.makePared() ) return unLab; } } Ejemplo: Laberinto

edu.red 41 Factoría Abstracta: Alternativa 1 Con métodos factoría

public abstract class WidgetFactory { public abstract Window createWindow(); public abstract Menu createScrollBar(); public abstract Button createButton(); }

public class MotifWidgetFactory extends WidgetFactory { public Window createWindow() {return new MotifWidow();} public ScrollBar createScrollBar() {return new MotifScrollBar();} public Button createButton() {return new MotifButton();} }

edu.red 42 Factoría Abstracta: Alternativa 1

// Código cliente

WidgetFactory wf = new MotifWidgetFactory();

Button b = wf.createButton();

Window w = wf.createWindow(); …

edu.red 43 Factoría Abstracta: Alternativa 2 Con prototipos

public class WidgetFactory { private Window protoWindow; private ScrollBar protoScrollBar; private Button protoButton; public WidgetFactory(Window wp, ScrollBar sbp, Button bf) { protoWindow = wp; protoScrollBar = sbp; protoButton = bp; }

public Window createWindow() {return (Window) protoWindow.clone(); } public ScrollBar createScrollBar() {return (ScrollBar) protoScrollBar.clone();} public Button createButton() {return (Button) protoButton.clone();} }

edu.red 44 Factoría Abstracta: Alternativa 2 // crea objetos de una jerarquía de productos class FactoriaProductos { private Hashtable catalogo; public Producto getProducto(String s) { return (Producto) ((Producto) catalogo.get(s)).clone(); } public FactoriaProductos (String familia) { “inicializa el catalogo”} … }

edu.red 45 Ejercicio Sea una herramienta para diseño y simulación de circuitos digitales que proporciona una paleta con elementos tales como puertas, diodos, interruptores, flip-flop,.., y que permite construir circuitos a partir de ellos. Los circuitos construidos por el usuario pueden ser añadidos a la paleta para ser utilizados directamente en la construcción de nuevos circuitos. Diseña una solución basada en patrones para el mecanismo de crear instancias de un nuevo circuito añadido a la paleta, describiendo la estructura de clases propuesta.

edu.red 46 Singleton Propósito Asegurar que una clase tiene una única instancia y asegurar un punto de acceso global. Motivación Un manejador de ventanas, o un spooler de impresoras o de un sistema de ficheros o una factoría abstracta. La clase se encarga de asegurar que exista una única instancia y de su acceso.

edu.red 47 Singleton Aplicabilidad Debe existir una única instancia de una clase, accesible globalmente. Consecuencias Acceso controlado a la única instancia Evita usar variables globales Generalizar a un número variable de instancias La clase Singleton puede tener subclases.

edu.red 48 Singleton (Sin subclases) public class Singleton { public static Singleton getInstancia() { if (unicaInstancia == null) unicaInstancia = new Singleton(); return unicaInstancia; } private Singleton() { }

private static Singleton unicaInstancia = null; private int dato = 0; public int getDato() {return dato;} public void setDato(int i) {dato = i;} }

edu.red 49 Ejemplo: Catálogo instancias prototípicas public class CatalogoCircuitos { public static CatalogoCircuitos getInstancia() { if (unicaInstancia == null) unicaInstancia = new CatalogoCircuitos(); return unicaInstancia; } private CatalogoCircuitos() { elems = new HashTable(); }

private static CatalogoCircuitos unicaInstancia = null; private Hashtable elems; public Circuito getCircuito(String id) { Circuito c = (Circuito) elems.get(id); return (Circuito) c.clone(); } public void addCircuito(String id,Circuito c) { elems.put(id,c); } }

Circuito sum = CatalogoCircuitos.getInstancia().getCircuito(“sumador”);

edu.red 50 Singleton (Con subclases) public class FactoriaLaberinto { public static FactoriaLaberinto instancia(String s) { if (unicaInstancia == null) unicaInstancia = Class.forName(s).newInstance(); return unicaInstancia ; }

protected FactoriaLaberinto () { } … }

Partes: 1, 2, 3, 4
 Página anterior Volver al principio del trabajoPágina siguiente