patrones de diseño - lsub.orglsub.org/ist/5.patrones.pdf · patrones de diseño • problemas...

44
Patrones de Diseño LSUB, GSYC, URJC Tuesday, February 26, 13

Upload: others

Post on 20-Aug-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Patrones de DiseñoLSUB, GSYC, URJC

Tuesday, February 26, 13

Page 2: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Patrones de Diseño

• Problemas comunes de programación

• Una buena solución

• Nombres para referirse a ellos

Tuesday, February 26, 13

Page 3: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Iterator

• Forma de recorrerse una colección

• Oculta los detalles de cómo está implementado

Tuesday, February 26, 13

Page 4: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Iterator

public boolean hasNext(); public Object next();

Tuesday, February 26, 13

Page 5: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 6: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 7: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 8: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Iterator en Java

• Tiene un método extra (opcional)

public void remove();

Tuesday, February 26, 13

Page 9: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 10: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 11: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 12: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Visitor

Tuesday, February 26, 13

Page 13: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Visitor• Todas las figuras deberían ser visitables:

public interface Visitable {

public void accept(Visitor visitor);}

Tuesday, February 26, 13

Page 14: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 15: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 16: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 17: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 18: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Factory

• Creación de nuevos objetos

• A partir de una descripción

• Sin especificar la clase concreta

Tuesday, February 26, 13

Page 19: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 20: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 21: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Factory• Ahora se puede crear una figura de la

descripcion:

f = FiguraFactory.produce(“circulo”);

Tuesday, February 26, 13

Page 22: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 23: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 24: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Prototype

• Es un factory que clona objetos

• A partir de uno dado

Tuesday, February 26, 13

Page 25: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 26: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 27: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Façade

• Interfaz unificado para un subsistema

• Simplificar el uso

• Desacoplar de detalles concretos

Tuesday, February 26, 13

Page 28: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 29: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 30: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Façade

class Usuario { public static void main(String[] args) { Computer facade = new Computer(); facade.startComputer(); }}

Tuesday, February 26, 13

Page 31: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 32: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 33: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 34: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 35: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 36: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 37: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 38: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 39: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 40: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 41: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

Strategy/Command

File file = getFile();FileBuf b = editorFactory.Load( file.size() );b.edit();

Tuesday, February 26, 13

Page 42: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 43: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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

Page 44: Patrones de Diseño - lsub.orglsub.org/ist/5.patrones.pdf · Patrones de Diseño • Problemas comunes de programación • Una buena solución • Nombres para referirse a ellos

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