06 Patrones

82
1 Reutilización del Software Patrones de Diseño

Transcript of 06 Patrones

Page 1: 06 Patrones

1

Reutilización del Software

Patrones de Diseño

Page 2: 06 Patrones

2

Introducción

• El diseño OO es difícil y el diseño de software orientado a objetos reutilizable lo es aún más.

• Los diseñadores expertos no resuelven los problemas desde sus principios; reutilizan soluciones que han funcionado en el pasado.– Se encuentran patrones de clases y objetos de

comunicación recurrentes en muchos sistemas orientados a objetos.

– Estos patrones resuelven problemas de diseño específicos y hacen el diseño flexible y reusable.

Page 3: 06 Patrones

3

Definición de un patrón

Alexander(arquitecto/urbanista)

Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno y describe también el núcleo de la solución al problema, de forma que puede utilizarse un millón de veces sin tener que hacer dos veces lo mismo.

Page 4: 06 Patrones

4

Definición de un patrón de diseño

[Gamma]Un patrón de diseño es una descripción

de clases y objetos comunicándose entre sí adaptada para resolver un problema de diseño general en un contexto particular.

Page 5: 06 Patrones

5

Introducción

• Es un tema importante en el desarrollo de software actual: permite capturar la experiencia

• Busca ayudar a la comunidad de desarrolladores de software a resolver problemas comunes, creando un cuerpo literario de base– Crea un lenguaje común para comunicar ideas y

experiencia acerca de los problemas y sus soluciones

• El uso de patrones ayuda a obtener un software de calidad (reutilización y extensibilidad)

Page 6: 06 Patrones

6

Elementos de un patrón

• Nombre: describe el problema de diseño.• El problema: describe cuándo aplicar el

patrón.• La solución: describe los elementos que

componen el diseño, sus relaciones, responsabilidades y colaboración.

Page 7: 06 Patrones

7

Más información en...

• Desing Patterns. E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns. Addison Wesley, 1995.

• Patterns Home Page: http://hillside.net/patterns/

• Thinking in patterns with javahttp://www.mindview.net/Books/TIPatterns/

Page 8: 06 Patrones

8

Clasificación de los patrones

• Según su propósito:– De creación: conciernen al proceso de creación

de objetos.– De estructura: tratan la composición de clases

y/o objetos.– De comportamiento: caracterizan las formas en

las que interactúan y reparten responsabilidades las distintas clases u objetos.

Page 9: 06 Patrones

9

Estructural ComportamientoCreación

Clase

Objeto

üFactory Method üAdapter InterpreterTemplate Method

Abstract Factory

Builder

Prototype

üSingleton

üAdapter

Bridge

üComposite

Decorator

üFacade

Flyweight

Proxy

Chain of ResponsabilityCommandüIterator

MediatorMementoüObserver

StateüStrategy

Visitor

Propósito

Ámbito

Además: PATRONES DE DISEÑO FUNDAMENTALES

Clasificación de los patronesGoF (gang of Four) [Gamma]

Page 10: 06 Patrones

10

Patrones de diseño fundamentales

Son patrones que no aparecen la tabla definida por Gamma, pero se utilizan habitualmente:

• DELEGATION

• INTERFACE

• MARKER INTERFACE

Page 11: 06 Patrones

11

Patrón DELEGATION

Utilidad:Cuando se quiere extender y reutilizar la funcionalidad de una clase SIN UTILIZAR LA HERENCIA

Ventajas:• En vez de herencia múltiple• Cuando una clase que hereda de otra quiere

ocultar algunos de los métodos heredados• Compartir código que NO se puede heredar

Page 12: 06 Patrones

12

Patrón DELEGATIONEl problema

Clase A

a1()….

Clase B

b1(),b2()….

Clase Ca1(), b1(), b2()

….

- El lenguaje utilizado NO PERMITE HERENCIA MÚLTIPLE

- La clase C no desea TODOS los métodos de B

Page 13: 06 Patrones

13

Patrón DELEGATIONLa solución

Clase A

a1()….

Clase B

b1(), b2()….

Clase Ca1(), b1()

….

NO USAR HERENCIA

SINO LA RELACIÓN “USA”

usa

El método b1() habrá que añadirlo a C

Page 14: 06 Patrones

14

Patrón DELEGATIONImplementación

class C extends A {

B objB;

C ( ) { // En la constructora se puede crear obj. de B

objB=new B();

}

void b1( ) { objB.b1( );}

….

Page 15: 06 Patrones

15

Patrón INTERFACEUtilidad y Ventajas

UtilidadDefinir un comportamiento independiente de donde vaya a ser utilizado

VentajasDesacople entre comportamiento y clase.Realización de clases “Utilities”

Page 16: 06 Patrones

16

Patrón INTERFACEEl problema

Utilities

void imprimirEstructura (????? o) {o.irAlPrimero();while (o.tieneElems() );

imprimir (o.obtenerSiguiente() );}

Todos los objeto o, tienen que implementar:irAlPrimero(), tieneElems(), obtenerSiguiente().

Problema: De qué tipo son los objetos o?

Page 17: 06 Patrones

17

Patrón INTERFACELa solución

Clase Utilities

ImprimirEstructura(Recorrible o)….

Interfaz Recorrible

irAlPrimero(), tieneElems(), obtenerSiguiente().

usa

Clase A

Solución: Definir los parámetros de un tipo Interfaz.Todas las clases(instancias) que quieran utilizar ese comportamiento deberán implementar dicho interfaz

implementa

irAlPrimero(), tieneElems(), obtenerSiguiente().

Page 18: 06 Patrones

18

Patrón INTERFACEImplementación

class MiClase<T> implements Recorrible<T> {

Vector<T> v=new Vector<T>();

int pos;

void irAlPrimero() { pos=0;}

boolean tieneElems() {v.lenght < pos;}

T obtenerSiguiente() {

T o=v.elementAt(pos); pos++;

return o; }

}

}

Page 19: 06 Patrones

19

Patrón INTERFACEEjemplo

// Estructuras de datos, algoritmos y predicados JGLArray queue = new Array( );queue.add( ...);

Counting.countIf(queue, new MayorEdad());

class MayorEdad implements UnaryPredicate {public boolean execute (Object o1){ ...... } }

Definición: Counting.countIf(Container,UnaryPredicate);

Uso de countIf

Page 20: 06 Patrones

20

Patrón MARKER INTERFACEUtilidad y Ventajas

• Utilidad– Sirve para indicar atributos semánticos de

una clase.

• Ventajas:– Se puede preguntar si un objeto pertenece

a una clase de un determinado tipo o no.– Habitualmente se utiliza en clases de

utilidades que tienen que determinar algo sobre objetos sin asumir que son instancias de una determinada clase o no.

Page 21: 06 Patrones

21

Patrón MARKER INTERFACE

Clase Utilidad

operacion(Object o)….

Interfaz Markerusa

Clase Marcadam1()….

Dentro del código del método operacion(Object o) de la clase Utilidad podemos preguntar si el objeto o es de una clase Marker:

if (o instanceof Marker) {...}

else {...}

Clase NoMarcadanm1()….

Page 22: 06 Patrones

22

Patrón MARKER INTERFACEEjemplo

En Java hay clases “serializables”, “cloneables”, etc. Para ello, basta con que implementen las interfaces Serializable, Cloneable, etc.

Page 23: 06 Patrones

23

Estructural ComportamientoCreación

Clase

Objeto

üFactory Method üAdapter InterpreterTemplate Method

Abstract Factory

Builder

Prototype

üSingleton

üAdapter

Bridge

üComposite

Decorator

üFacade

Flyweight

Proxy

Chain of ResponsabilityCommandüIterator

MediatorMementoüObserver

StateüStrategy

Visitor

Propósito

Ámbito

Clasificación de los patronesGoF (gang of Four) [Gamma]

Page 24: 06 Patrones

24

Patrón SINGLETON

• Utilidad– Asegurar que una clase tiene una sola instancia y

proporcionar un punto de acceso global a ella

• Ventajas– Es necesario cuando hay clases que tienen que

gestionar de manera centralizada un recurso– Una variable global no garantiza que sólo se instancie

una vez

Page 25: 06 Patrones

25

Patrón SINGLETONLa solución

Clase CSingleton

- CSingleton laInstancia….- CSingleton ()+ getInstance ()

Atributos

Métodos

- indica que es private + indica que es public

Método static

– El constructor de la clase DEBE SER PRIVADO

– Se proporciona un método ESTÁTICO en la clase que devuelve LA ÚNICA INSTANCIA DE LA CLASE: getInstance()

Page 26: 06 Patrones

26

Patrón SINGLETONImplementación

public class CSingleton {

private static CSingleton laInstancia = new CSingleton();

private CSingleton() {}

public static CSingleton getInstance() {

return laInstancia;

}

………………………….

}

Page 27: 06 Patrones

27

Patrón SINGLETONInconvenientes

Se podría obtener una nueva instancia usando el esquema anterior:

public class MiCSingleton extends CSingleton

implements Cloneable {}

MiCSingleton mcs = new MiCSingleton();

MiCSingleton mcsCopia = mcs.clone();

Para solucionarlo: definir CSingleton como finalpublic final class CSingleton {...}

Page 28: 06 Patrones

28

public final class Facultad implements Serializable {private Vector listaProfesores;private Vector listaEstudiantes;private Vector listaAsigs;private Vector listaMatrs;private static Facultad laFacultad=new Facultad();private Facultad() // EL CONSTRUCTOR ES PRIVADO{ listaProfesores = new Vector(); // Sólo hay UNA instancia

listaEstudiantes= new Vector(); // y se guarda en laFacultadlistaAsigs = new Vector();listaMatrs = new Vector(); }

public static Facultad getInstance() {return laFacultad;}public Vector obtListaProfesores()

{return listaProfesores;}public void anadirProfesor(Profesor p)

{listaProfesores.addElement(p); }

EJEMPLO DE PATRÓN

SINGLETON

Page 29: 06 Patrones

29

UtilidadSeparar la clase que crea los objetos, de la jerarquía de objetos a instanciar

Ventajas– Centralización de la creación de objetos– Facilita la escalabilidad del sistema– El usuario se abstrae de la instancia a crear

Patrón FACTORY METHOD

Page 30: 06 Patrones

30

Patrón FACTORY METHODEl problema

Clase A

oper1()oper2()...

Clase A’

oper1()oper2()...

Clase A’’

oper1()oper2()...

If (tipo==1)create A’elsecreate A’’

Programa1

If (tipo==1)create A’elsecreate A’’

Programa2

Problema: Qué sucede si queremos añadir A’’’?

Page 31: 06 Patrones

31

Patrón FACTORY METHODUna primera solución

Clase A

oper1()oper2()static A create(tipo)

Clase A’

oper1()oper2()...

Clase A’’

oper1()oper2()...

A.create(1);

Programa1

A.create(2)

Programa2

Solución: Hay que recompilar todas las clases que heredan de A

Puede que no tengamos acceso al código de A

Page 32: 06 Patrones

32

Patrón FACTORY METHODLa solución final

Interfaz A

oper1()oper2()...

Clase CFactoryA create(tipo)

….

Solución: Separar el creador de las instancias de la propia claselas instancias se crean en una clase CFactory

Clase A1

oper1()oper2()...

Clase A2

oper1()oper2()...

Page 33: 06 Patrones

33

Patrón FACTORY METHOD

class Aplicación {...A newA(...) {

A miA;CFactory fact= new CFactory(); ...miA = fact.create(“TIPO 2”);... return miA; }

• No se crean las instancias directamente en Aplicación

• Si se quisiera añadir un nuevo A A’’’, NO NECESARIAMENTE habría que modificar la clase Aplicación. Los tipos que CFactory puede crear los puede devolver un método y Aplicación trabajar con él.

Page 34: 06 Patrones

34

Patrón FACTORY METHOD

class CFactory {...A create(String tipo) {

if (“TIPO 1”.equals(tipo))

return new A1();

else if (“TIPO 2”.equals(tipo))

return new A2(); .... }• Se crean las instancias de los Aes en CFactory, no en la clase Aplicación

• Se pueden añadir nuevos Aes sin modificar Aplicación. Basta con añadir la clase A3 y modificar CFactory (añadir el tipo correspondiente a dicho A: “TIPOX”)

Page 35: 06 Patrones

35

Estructural ComportamientoCreación

Clase

Objeto

üFactory Method üAdapter InterpreterTemplate Method

Abstract Factory

Builder

Prototype

üSingleton

üAdapter

Bridge

üComposite

Decorator

üFacade

Flyweight

Proxy

Chain of ResponsabilityCommandüIterator

MediatorMementoüObserver

StateüStrategy

Visitor

Propósito

Ámbito

Clasificación de los patronesGoF (gang of Four) [Gamma]

Page 36: 06 Patrones

36

Patrón ADAPTER

IntenciónConvertir la interfaz de una clase en otra interfaz esperada por los clientes. Permite que clases con interfaces incompatibles se comuniquen

VentajasSe quiere utilizar una clase ya existente y su interfaz no se corresponde con la interfaz que se necesitaSe quiere envolver código no orientado a objeto con forma de clase

Page 37: 06 Patrones

37

Patrón ADAPTEREl problema

Clase A usa Interfaz C

Clase B

m1(….)m2(….)….

b1(….)b2(….)….

Se desea utilizar la clase A (el método ejec) utilizando como entrada un objeto de la clase B

objetoDeA.ejec(objetoDeB)

Pero no se puede, ya que la clase B no implementa la interfaz C

ejec(Interfaz C)

Page 38: 06 Patrones

38

Patrón ADAPTERLa solución

usaInterfaz C

m1(….)m2(….)….

Clase Bb1(….)b2(….)….

Clase Aejec(Interfaz C)

Solución: construir una clase Adaptadora de B que implemente la interfaz C. Al implementarla, usa un objeto de B y sus métodos

Clase AdapterB

m1(….)m2(….)….

usa

Para utilizar la clase A: objetoDeAdapterB =NEW AdapterB(objetoDeB)

AdapterB(B)

objetoDeA.ejec(objetoDeAdapterB)

Page 39: 06 Patrones

39

Patrón ADAPTERDiagrama de interacción

El cliente quiere usar el objeto a (para que ejecute el método ejec) con un objeto de b. Para ello necesita crear un objeto adaptador que encapsule b

ab: AdapterBnew AdapterB(b)

ejec(ab)ab

a : A

m1(...)b1()

b : B

m2(...)b2()

: Cliente

Page 40: 06 Patrones

40

Patrón ADAPTER

• Convierte la interfaz de una clase en otra interfaz que los clientes esperan. Permite que clases con interfaces incompatibles puedan ser utilizadas conjuntamente.– La interfaz de la clase B (los métodos

b1(),b2()…) los convierte/adapta a los métodos esperados por la clase A (métodos m1(),m2(),…)

Page 41: 06 Patrones

41

Patrón ADAPTER Ejemplo de uso en JGL

usaInterfaz Sequence

Array Java nativo: int[]

Clase Sortingsort(Sequence)

OBJETIVO: PODER USAR LOS ALGORITMOS DE JGL CON int []int ints[] = { 3, -1, 2, -3, 4 };IntArray intArray = new IntArray( ints );Sorting.sort( intArray );

Clase IntArrayusa

IntArray(int [] )

add, clear, isEmpty, size. (de Container)at, put, contains, ...

Operaciones con arrays:

acceso elº i: int[i], ...

Implementa: add, clear, isEmpty, size.. Adapter proporcionado por JGL

De JGL

De Java

Page 42: 06 Patrones

42

Patrón ADAPTEREjemplo I

class WhatIUse {public void op(WhatIWant wiw) { wiw.f();} }

class WhatIHave {public void g() {}public void h() {} }

class Adapter implements WhatIWant {WhatIHave whatIHave;public Adapter(WhatIHave wih) {whatIHave = wih; }

public void f() {// Implementa usando los // métodos de WhatIHave:whatIHave.g();whatIHave.h(); } }

interface WhatIWant { void f(); }

Page 43: 06 Patrones

43

Gráfico

Dibujar( )

Mover( )

Polígono

Dibujar( )

Mover( )

Cuadrado

Dibujar( )

Mover( )

Círculo

Dibujar( )

Mover( )

Label

Draw( )

Move( )

Texto

Dibujar( )

Mover( )

♦Extender un editor gráfico con clases de otro toolkit

Patrón ADAPTEREjemplo II

Page 44: 06 Patrones

44

Patrón COMPOSITE

Intención

Componer objetos en jerarquías todo-parte y permitir a los clientes tratar objetos simples y compuestos de manera uniforme

Ventajas♦Permite tratamiento uniforme de objetos simples y complejos así como composiciones recursivas♦Simplifica el código de los clientes, que sólo usan una interfaz♦Facilita añadir nuevos componentes sin afectar a los clientes

Inconvenientes♦Es difícil restringir los tipos de los hijos♦Las operaciones de gestión de hijos en los objetos simples pueden presentar problemas: seguridad frente a flexibilidad

Page 45: 06 Patrones

45

Patrón COMPOSITEEl problema: La escalabilidad

Documento

Página

MarcoColumna

ImagenLíneaDeTexto

Carácter

Un documento está formado por varias páginas, las cuales están formadas por columnas que contienen líneas de texto, formadas por caracteres.

Las columnas y páginas pueden contener marcos. Los marcos pueden contener columnas.

Las columnas, marcos y líneas de texto pueden contener imágenes.

Page 46: 06 Patrones

46

Patrón COMPOSITELa solución

ElementoDeDocumento

Carácter Imagen ElemDeDocCompuesto

Documento Página Columna Marco LíneaDeTexto

Un documento está formado por varias páginas, las cuales están formadas por columnas que contienen líneas de texto, formadas por caracteres. Las columnas y páginas pueden contener marcos. Los marcos pueden contener columnas. Las columnas, marcos y líneas de texto pueden contener imágenes.

0..n

Page 47: 06 Patrones

47

Patrón COMPOSITELa solución

para cada hijo en m_hijohijo->Operación();

SimpleOperación()

Compuesto

Operación()Add(c : Componente)Remove(c : Componente)Iterar() : Componente

m_hijoCliente Componente

Operación() unCompuesto

unCompuesto

unSimpleunSimpleunSimple

unSimple unSimple

♦Participantes

♦Componente: declara una clase abstracta para la composición de objetos,

♦Simple: representa los objetos de la composición que no tienen hijos eimplementa sus operaciones

♦Compuesto: implementa las operaciones para los componentes con hijos y almacena a los hijos

♦Cliente: utiliza objetos de la composición mediante la interfaz de Componente

Page 48: 06 Patrones

48

Patrón COMPOSITEEjemplo: La jerarquía de clases de AWT

• Sirve para diseñar clases que agrupen a objetos complejos, los cuales a su vez están formados por objetos complejos y/o simples

• La jerarquía de clases AWT se ha diseñado según el patrón COMPOSITE

Page 49: 06 Patrones

49

Patrón COMPOSITE Ejemplo: La jerarquía de clases de AWT

COMPONENTE

CONTENEDOR (todo contenedor es un componente)

Applet

Las posibilidades son infinitas…

- Una ventana formada por 2 cajas de texto, 2 campos de texto, 3 botones, 1 panel que contenga 5 casillas de validación y una lista desplegable.-Una ventana formada por 2 etiquetas, 2 campos de texto y un botón-…Además, añadir nuevos tipos de contenedores y de componentes no sería muy costoso (estaríamos ante una solución extensible)

Page 50: 06 Patrones

50

Patrón COMPOSITE Un diseño francamente malo …

Frame

Button

CheckBox

TextField…

- Se necesitarían métodos addButton, addCheckBox, addTextField,addFrame en la clase Frame (y los correspondientes a todos los que faltan)- Además el diagrama está muy incompleto, ya que un Button puede sercomponente de un Panel, Dialog, … - Si se quisiera añadir un nuevo componente XXX, habría que cambiar laclase Frame y añadir el método addXXX (nada extensible)

**

*

*

Page 51: 06 Patrones

51

Componentes principales de Swing

JComponent

JFrameJWindow

JPanelJDialog

JList JComboBox

JMenuBar

JTextField, JTextArea, JButton…

Applet

JApplet

Page 52: 06 Patrones

52

Intención: El patrón FACADE simplifica el acceso a un conjunto de clases proporcionando una única clase que todos utilizan para comunicarse con dicho conjunto de clases.

Ventajas– Los clientes no necesitan conocer las clases que

hay tras la clase FACADE– Se pueden cambiar las clases “ocultadas” sin

necesidad de cambiar los clientes. Sólo hay que realizar los cambios necesarios en FACADE

Patrón FACADE

Page 53: 06 Patrones

53

Patrón FACADEEl problema

Clase A

a1()….

Clase D

d1()….

Clase C

c1()….

Clase B

b1()….

usa

usa

usa

….

Clase CLIENTE

Clases SERVIDORAS

La clase A debe saber cuál es exactamente la clase que le proporciona el servicio: b1() es de B, c1() de C, d1() de D, ...

Page 54: 06 Patrones

54

Patrón FACADEEl problema

Clase CLI1

cl11()….

Clase D

d1()….

Clase C

c1()….

Clase B

b1()….

usa

usa...

….

Clases CLIENTES Clases SERVIDORAS

Problema: Además puede haber muchas clases cliente...

Clase CLI2cl21()….

Clase CLI3

cl31()….

Page 55: 06 Patrones

55

Patrón FACADELa solución

Clase CLI1

cl11()….

Clase D

d1()….

Clase C

c1()….

Clase B

b1()….

….

Clases CLIENTES Clases SERVIDORAS

Solución: Proporcionar una clase que implemente todos los servicios (b1()…). Los clientes sólo usarán dicha clase.

Clase CLI2cl21()….

Clase CLI3cl31()….

Clase Facade

b1(), c1(), d1(),..

usausa

public class Facade {B objB = new B();C objC = new C();…void b1() { objB.b1();}..}

Page 56: 06 Patrones

56

Compilador

Clases del subsistema decompilación

EditorDepurador

Linkador

Token

AnaLexAnaSin

ASA TabSim

Compilar()

Patrón FACADEEjemplo: Estructurar un entorno de programación

Page 57: 06 Patrones

57

Estructural ComportamientoCreación

Clase

Objeto

üFactory Method üAdapter InterpreterTemplate Method

Abstract Factory

Builder

Prototype

üSingleton

üAdapter

Bridge

üComposite

Decorator

üFacade

Flyweight

Proxy

Chain of ResponsabilityCommandüIterator

MediatorMementoüObserver

StateüStrategy

Visitor

Propósito

Ámbito

Clasificación de los patronesGoF (gang of Four) [Gamma]

Page 58: 06 Patrones

58

• Intención– Definir una dependencia 1:n de forma que

cuando el objeto 1 cambie su estado, los nobjetos sean notificados y se actualicen automáticamente

• Motivación– En un toolkit de GUI, separar los objetos

de presentación (vistas) de los objetos de datos, de forma que se puedan tener varias vistas sincronizadas de los mismos datos (editor-subscriptor)

Patrón OBSERVER

Page 59: 06 Patrones

59

a = 50%b = 30%c = 20%

notificación de cambiopeticiones, modificaciones

sujeto

observadores

Patrón OBSERVEREjemplo

Page 60: 06 Patrones

60

Clases OBSERVADORAS(Vistas)

Interfaz Observer

update()….

Clase OBSERVADA(Modelo)

susObservers

0..*

Clase ObsConcreta

update() { // Qué hacer cuando // cambie el “objeto // observado” suSubject

// Llamará: suSubject.get() } ...

suSubject

Se implementa añadiendo el atributo Observable suSubjecten ObsConcreta

Se implementa añadiendo el atributo Vector susObserversen Subject

Class ObsConcreto

set(...){// call notifyObservers()}

get() {...}.....

1

Class Observable addObserver(Observer)removeObserver(Observer)notifyObservers()setChanged()

Patrón OBSERVERLa solución

Page 61: 06 Patrones

61

Patrón OBSERVERDiagrama de interacción

s: Observable oi: Observer

set(...)

update()Llama a update() para cada objeto de susObservers

get(...)

“actualizarse con los nuevos valores” de s

addObserver(oi) Registrarse como “observador” de s

Se cambia algún valor de s

setChanged()

notityObservers()

Page 62: 06 Patrones

62Este método es invocado cuando el objeto observado ha cambiadoupdate()

countObserversdeleteObserversdeleteObserver(o)addObserver (o)Métodos

notifyObservers

hasChangedsetChanged()

Devuelve el número de observadoresElimina todos los observadoresElimina el observador oAñade un nuevo observador o

Notifica a todos los objetos suscritos si el objeto esta enEstado “modificado”

Devuelve cierto si el objeto esta “modificado”marca el objeto como “modificado”

Significado

Patrón OBSERVERLa clase Observable

La interfaz Observer

Page 63: 06 Patrones

63

Patrón OBSERVEROtro Ejemplo

http://csis.pace.edu/~bergin/mvc/mvcgui.html

Building Graphical User Interfaces with the MVC Pattern

Page 64: 06 Patrones

64

Patrón OBSERVEREjemplo: La clase Observable (el modelo)

package mvc;import java.util.*;public class Observado extends java.util.Observable{

public double getF(){return temperatureF;}public double getC(){return (temperatureF - 32.0) * 5.0 / 9.0;}public void setF(double tempF){

temperatureF = tempF;setChanged();notifyObservers();

}public void setC(double tempC){

temperatureF = tempC*9.0/5.0 + 32.0;setChanged();notifyObservers();

}private double temperatureF = 32.0;

}

Page 65: 06 Patrones

65

Patrón OBSERVEREjemplo: La clase Observer (la vista)

public class Observador implements java.util.Observer{

private Observado modelo;public Observador(Observado model){modelo=model;model.addObserver(this); // Conecta la Vista con el Modelo}public void update(Observable t, Object o) // Invocada desde el modelo

{ System.out.println("La temperatura ha cambiado" + modelo.getF());}

}

Page 66: 06 Patrones

66

Patrón OBSERVEREjemplo: El programa principal

public static void main(String[] args) {Observado o=new Observado();Observador ob=new Observador(o);Observador2 ob2=new Observador2(o);

o.setF(45.5); }

The temperature has changed45.5

La temperatura ha cambiado45.5

Process exited with exit code 0.

Page 67: 06 Patrones

67Ejemplo de patrón OBSERVER

OBSERVABLE

OBSERVER

Page 68: 06 Patrones

68

...public class ObserverQuePinta extends Frame

implements Observer{Label label1 = new Label();Panel panel1 = new Panel();Observable suSubject;

public ObserverQuePinta(Observable s) {suSubject = s;s.addObserver(this);

}public void update() {

String c = suSubject.getColor();if (c.equals("ROJO")) panel1.setBackground(Color.red);else if (c.equals("VERDE")) panel1.setBackground(Color.green);else if (c.equals("AZUL")) panel1.setBackground(Color.blue);

} }

public interface Observer {void update();

}

VISTA

Page 69: 06 Patrones

69

public class Subject extends Observable {Choice choice1 = new Choice();public Subject() {

choice1.addItem("ROJO"); choice1.addItem("VERDE");choice1.addItem("AZUL");choice1.addItemListener(new java.awt.event.ItemListener() {

public void itemStateChanged(ItemEvent e) {setChanged();notifyObservers(); }}

}public String getColor() {return choice1.getSelectedItem();}

}

MODELO

Page 70: 06 Patrones

70

Subject s = new Subject();Observer o1 = new ObserverQuePinta(s);Observer o2 = new ObserverQuePinta(s);

CREACIÓN DE OBJETOS SUBJECT Y OBSERVER

Patrón OBSERVERInicialización

Page 71: 06 Patrones

71

• Si se quisiera añadir un nuevo OBSERVER que en vez de pintar escribiera un número para cada color (1 si ROJO, 2 si VERDE, 3 si AZUL), ¿qué habría que hacer?– Escribir nueva clase OBSERVER que implemente

“notificar”• Si se quisiera cambiar el SUBJECT para

escoger el color pinchando un Checkbox en vez de escogerlo de un Choice– Hay que sustituir el Subject y llamar a “notificar”

de los observers cuando se seleccione un nuevo Checkbox

A

B

Patrón OBSERVERAdaptabilidad de la solución

Page 72: 06 Patrones

72

...public class ObserverQueEscribeNums extends Frame

implements Observer{Label label1 = new Label();TextArea textArea1 = new TextArea();Subject suSubject;public ObserverQueEscribeNums(Subject s) {

suSubject = s;s.addObserver(this); ... }

public void update() {String c = suSubject.getColor();if (c.equals("ROJO"))

textArea1.append("NUEVO COLOR: "+1+"\n");else if (c.equals("VERDE"))

textArea1.append("NUEVO COLOR: "+2+"\n");else if (c.equals("AZUL"))

textArea1.append("NUEVO COLOR: "+3+"\n");} }

public interface Observer {void notificar();

}

EXTENDER CON UN NUEVO OBSERVER

A

Page 73: 06 Patrones

73

...public class Subject extends Frame {Checkbox checkbox1 = new Checkbox(); Checkbox checkbox2 = new Checkbox(); // ... y checkbox3CheckboxGroup checkboxGroup1 = new CheckboxGroup();public Subject() {

checkbox1.setLabel("ROJO");checkbox1.setCheckboxGroup(checkboxGroup1);checkbox1.addItemListener(new java.awt.event.ItemListener() {

public void itemStateChanged(ItemEvent e) {notificar(); } });

checkbox2.setLabel("VERDE"); // y checkbox3.setLabel("AZUL");...public void addObserver(Observer o) {susObservers.addElement(o);}public void notificar() {

setChanged();notifyObservers(); } }

public String getColor() {return checkboxGroup1.getSelectedCheckbox().getLabel();} }

CAMBIAR DE SUBJECT

B

Page 74: 06 Patrones

74

Page 75: 06 Patrones

75

Intención:– Encapsular algoritmos relacionados en

clases y hacerlos intercambiables.– Se permite que la selección del algoritmo

se haga según el objeto que se trate.

Ventajas– Se permite cambiar el algoritmo

dinámicamente– Se eliminan sentencias condicionales para

seleccionar el algoritmo deseado

Patrón STRATEGY

Page 76: 06 Patrones

76

MétodoResolución

Resolver()

SistemaLineal

... Resolver () ...

MétodoResolución1

Resolver ()

MétodoResolución2

Resolver ()

MétodoResolución3

Resolver ()

instancia->Resolver();

Patrón STRATEGY La solución

Page 77: 06 Patrones

77

Patrón STRATEGY

Clase Cliente

….

Clase StrConcr1

operac()….

Interfaz Strategy

operac()….

usa

….

0..11

Clase StrConcr2

operac()….

La clase Cliente necesita ejecutar un método: operac(), que puede ser implementado siguiendo distintos algoritmos. Se pueden implementar todos ellos (en las clases StrConcrX) y ser trasparente a Cliente.

Page 78: 06 Patrones

78

Patrón STRATEGYImplementación

class Cliente {

Strategy s;

// PARA SELECCIONAR EL ALGORITMO// SE ASIGNA A s LA INSTANCIA// DE LA SUBCLASE QUE LO IMPLEMENTA

Cliente(Strategy str) {s = str;}

// EL Cliente SIEMPRE SE EJECUTARÁ ASÍ: s.operac(); }

Cliente c = new Cliente(new StrConcr1());

Se indica cuál es el algoritmo que se ejecutará

Page 79: 06 Patrones

79

Patrón STRATEGYImplementación

class Cliente {

// EN VEZ DE:

if (cond1) operac1();

else if (cond2) operac2();

else ...

}

• Sentencias condicionales para seleccionar el algoritmo

• Si se quisiera añadir una nueva forma de ejecutar operac() entonces HABRÍA QUE CAMBIAR EL CÓDIGO DE LA CLASE Cliente

Page 80: 06 Patrones

80

• Intención:– Proporcionar una forma de acceder a los

elementos de una colección de objetos de manera secuencial sin revelar su representación interna. Define una interfaz que declara métodos para acceder secuencialmente a la colección.

• Ventajas:– La clase que accede a la colección solamente a

través de dicho interfaz permanece independiente de la clase que implementa la interfaz.

Patrón ITERATOR

Page 81: 06 Patrones

81

Cliente

IteradorConcreto

Interfaz IteradorhasNextItem()getNextItem()

Interfaz AgregadoCrearIterador() : Iterador

AgregadoConcretoCrearIterador() : Iterador hasNextItem()

getNextItem()

♦Participantes♦Iterador: define una interfaz para acceder a los elementos del agregado y recorrerlos

♦IteradorConcreto: implementa la interfaz de Iterador y mantiene la posición actual del recorrido

♦Agregado: define una interfaz para crear un objeto iterador

♦AgregadoConcreto: implementa la interfaz de creación del iteradorpara devolver una instancia apropiada de IteradorConcreto

return new IteradorConcreto(this);

Patrón ITERATOR

Page 82: 06 Patrones

82

• Ejemplos en Java:

Patrón ITERATOR

Vector listOfStudents = new Vector();// PARA RECORRER EL VECTOR:

Enumeration list = listOfStudents.elements();while ( list.hasMoreElements() )

System.out.println( list.nextElement() );

Hashtable anIndex = new Hashtable();// PARA RECORRER LA TABLA HASH:

Enumeration list = anIndex.keys();while ( list.hasMoreElements() )

System.out.println( list.nextElement() );