Patrones de DiseñoLSUB, GSYC, URJC
Tuesday, February 26, 13
Patrones de Diseño
• Problemas comunes de programación
• Una buena solución
• Nombres para referirse a ellos
Tuesday, February 26, 13
Iterator
• Forma de recorrerse una colección
• Oculta los detalles de cómo está implementado
Tuesday, February 26, 13
Iterator
public boolean hasNext(); public Object next();
Tuesday, February 26, 13
Iterator en Java
• Las colecciones tienen un método iterator() que devuelve un Iterator
• Hay un interfaz Iterable:
• Hay una construcción especial llamada foreach que actúa sobre iterables
public interface Iterable<T> { public Iterator<T> iterator(); }
Tuesday, February 26, 13
Iterator en Java(azucar sintáctico)
/* Bla implementa Iterable<T> */ Bla bs = new Bla();
for(Bla b: bs) System.out.println("bla:" + b);
Tuesday, February 26, 13
Iterator en Java(equivalente)
/* Bla implementa Iterable<Xbla> */ Bla bs = new Bla(); Iterator<Xbla> i = bs.iterator();
for(Xbla b = i.next(); i.hasNext(); b = i.next()) System.out.println("bla:" + b);
Tuesday, February 26, 13
Iterator en Java
• Tiene un método extra (opcional)
public void remove();
Tuesday, February 26, 13
Visitor
• Tengo una operación nueva
• Para un grupo de clases en una estructura de datos
• Quiero poder cambiar la implementación
• Implemento un visitor
Tuesday, February 26, 13
Visitor
• El truco se basa en la sobrecarga de métodos
• El visitor tiene un método muy sobrecargado
• Una implementación para cada clase que visita
Tuesday, February 26, 13
Visitor
• Imaginemos que tenemos muchos tipos de figuras, Elipse, Círculo, Estrella... en un árbol
• Y queremos representarlas de diferentes formas
• De forma gráfica, en texto...
• Para cada representación habría un Visitor
• El visitor recorre el árbol visitando cada elemento
Tuesday, February 26, 13
Visitor
Tuesday, February 26, 13
Visitor• Todas las figuras deberían ser visitables:
public interface Visitable {
public void accept(Visitor visitor);}
Tuesday, February 26, 13
Visitor• El visitor es el que hace el trabajo:
public interface Visitor {
public void visit(Elipse e); public void visit(Estrella x); public void visit(Tree t); ...}
Tuesday, February 26, 13
Visitor• La figura llama al Visitor:
public class Figura implements Visitable, Figura {
...
@Override public void accept(Visitor visitor) { visitor.visit(this); } ...}
Tuesday, February 26, 13
Visitor• La un árbol llama al Visitor:public class Figura implements Visitable, Tree {
Tree right, left;
Figura fig;
@Override public void accept(Visitor visitor) { visitor.visit(this); } ...}
Tuesday, February 26, 13
Visitorpublic class GraphicVisitor implements Visitor { @Override public void visit(Elipse e) { //dibujar elipse } @Override public void visit(Rectangulo r) { //dibujar rectangulo }
@Override public void visit(Tree t) { visit(t.fig); visit(t.left); visit(t.right); } ...}
Tuesday, February 26, 13
Factory
• Creación de nuevos objetos
• A partir de una descripción
• Sin especificar la clase concreta
Tuesday, February 26, 13
Factory• Imaginemos que leemos de un fichero
• La descripción de una figura
• No sabemos qué tipo de figura vamos a crear
nombreFig = br.readLine();Figura = new ?????
Tuesday, February 26, 13
Factorypublic class FiguraFactory { ... public static Figura produce(String desc){ TipoFigura tf = TipoFigura.Valueof(desc); Figura f; switch(tf) { case ELIPSE: f = new Elipse(); break; case CIRCULO: f = new Circulo(); break; ... } } ... return tf;}
Tuesday, February 26, 13
Factory• Ahora se puede crear una figura de la
descripcion:
f = FiguraFactory.produce(“circulo”);
Tuesday, February 26, 13
Factory• Si vamos a crear muchos iguales, igual es
mejor crear un objeto factoría de ese tipo:
public class CirculoFactory { int r; Punto pos; CirculoFactory(int r, Punto pos) { rad = r; center = new Punto(pos.x, pos.y); } public Circulo produce(){ Circulo f = new Circulo(rad, center); break; } return f;}
Tuesday, February 26, 13
Factory• Si vamos a crear muchos iguales, es mejor
crear un objeto factoría de ese tipo.
• La descripción se le da a la factoría y luego se producen como churros:
circFact = new CirculoFactory(2, new Punto(2, 3));
circ = circFact.produce();
circ2 = circFact.produce();
Tuesday, February 26, 13
Prototype
• Es un factory que clona objetos
• A partir de uno dado
Tuesday, February 26, 13
Singleton
• Una única instancia del objeto
• No tiene sentido que haya más de uno
• Un método de clase devuelve la instancia
Tuesday, February 26, 13
Singleton/* Sólo hay un universo!! */public class Universo { ... private static final Universo universo = new Universo(0, 0);
public static Punto getInstance() { return universo; } ...}
Tuesday, February 26, 13
Façade
• Interfaz unificado para un subsistema
• Simplificar el uso
• Desacoplar de detalles concretos
Tuesday, February 26, 13
Façadeclass Cpu { public void freeze() { ... } public void jump(long position) { ... } public void execute() { ... }} class Memory { public void load(long position, byte[] data{ ... }} class HardDrive { public byte[] read(long lba, int size) { ... }}
Tuesday, February 26, 13
Façade class Computer { private Cpu cpu; private Memory memory; private HardDrive hardDrive; public Computer() { this.cpu = new Cpu(); this.memory = new Memory(); this.hardDrive = new HardDrive(); } public void startComputer() { cpu.freeze(); memory.load(BOOT_ADDRESS, hardDrive.read(MBR, SECT_SIZE)); cpu.jump(BOOT_ADDRESS); cpu.execute(); } }
Tuesday, February 26, 13
Façade
class Usuario { public static void main(String[] args) { Computer facade = new Computer(); facade.startComputer(); }}
Tuesday, February 26, 13
Wrapper/Adapter/Decorator
• Wrapper: envolver un objeto con otro
• Si el wrapper es para cumplir un interfaz se llama Adapter
• Para combinar funcionalidades se llama Decorator
Tuesday, February 26, 13
Wrapperpublic interface TextFragment { public String getTexto();}public class Capitulo implements TextFragment { private String texto; private int nCap;
public String getTexto() { return "Capítulo " + nCap + ":\n" + texto; }}public class HtmlWrapper implements TextFragment { private TextFragment wrapped;
public HtmlWrapper(TextFragment textF) { this.wrapped = textF; } public String getText() { return "<p>" + wrapped.getTexto() + "</p>"); }}
Tuesday, February 26, 13
Observer
• Tengo un conjunto de objetos interesados en cambios
• Un objeto (Subject o sujeto) notifica a los Observer
• En Java a los Observer se les suele llamar Listener
Tuesday, February 26, 13
Observer
• Imaginemos que tenemos un botón para cerrar la ventana
• Queremos que se entere la ventana (para cerrarse)
• Queremos que se entere la aplicación
Tuesday, February 26, 13
Observer
Boton b = new Boton("salir"); b.register(ventana); b.register(aplicacion)
• Cuando alguien pinche en el botón de salir
• Aviso a la ventana para que se cierre
• Y a la aplicación para que salve el estado.
Tuesday, February 26, 13
Observer
interface Observer { public void update(Evento click);}
interface Observable { public void register(Observer observer);
public void dettach(Observer observer);
public void notifyAll();}
Tuesday, February 26, 13
Observerclass Boton implements Observable { private ArrayList<Observer> observers = new ArrayList<Observer>(); private bool pulsado; ... @Override public void register(Observer observer) { observers.add(observer);
} @Override public void dettach(Observer observer) { observers.remove(observer);
}
@Override public void notifyAll() { for (Observer ob : observers) { ob.update(new Event(pulsado)); } }
public void setPulsado(bool click) { pulsado = click; notifyObservers(); }}
Tuesday, February 26, 13
Observerclass Ventana implements Observer { ... @Override public void update(Event click) { ... exit(); }}
class Applicacion implements Observer { ... @Override public void update(Event click) { ... saveState(); }}
Tuesday, February 26, 13
Strategy/Command
• Definir una familia de algoritmos
• Con el mismo interfaz
• Hacerlos intercambiables
• En tiempo de ejecución se elige uno
Tuesday, February 26, 13
Strategy/Command
• Creas un Objeto y lo configuras
• Un método execute() que hace el trabajo
• Oculta la complejidad de la implementación
Tuesday, February 26, 13
Strategy/Command
File file = getFile();FileBuf b = editorFactory.Load( file.size() );b.edit();
Tuesday, February 26, 13
Strategy/Commandinterface FileBuf { public void muestra();}
class CargaDirecta implements FileBuf { ...
public void edit() { // carga entero en un array (pequeño) }}
class CargaEnDemanda implements Filebuf {...
public void edit() { // carga en demanda (si es grande) } }
Tuesday, February 26, 13
Proxy
• Objeto que representa a otro
• Así se puede tener:
• El objeto representado en otra máquina
• Comprobar cosas adicionales antes de llamar al método
• Tener una instancia compartida y varios representantes (el objeto es caro)
Tuesday, February 26, 13
Model/View/Controller (MVC)
• Tres tipos de componentes:
• Controller: manda comandos al Model
• Model: actualiza el View
• View: presenta al usuario la información
• El usuario manda su entrada al Controller y recibe la información del View
Tuesday, February 26, 13