La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Patrones de Comportamiento: Patrón de Diseño Observer

Presentaciones similares


Presentación del tema: "Patrones de Comportamiento: Patrón de Diseño Observer"— Transcripción de la presentación:

1 Patrones de Comportamiento: Patrón de Diseño Observer
David Inocente Romero Escalona Rosa Hernández Alias Jacinto José Cruz Nieto

2 Patrones de Comportamiento
Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor

3 Patrón Observer Define una dependencia entre objetos de uno (subject) a muchos (observers). Unos ciertos eventos son notificados por el subject a todos los observers que dependen de él, lo cuales realizan una cierta tarea en consecuencia. Establece dos comportamientos comunes: Uno entre todos los objetos subjects. Otro entre todos los objetos observers. Para ello usa dos clases abstractas: Subject y Observer.

4 Patrón Observer Este patrón (algunas veces conocido como editor/subscriptor) es un patrón de diseño usado en programación para observar el estado de un objeto en un programa. Está relacionado con el principio de invocación implícita. Está usado como un sistema de detección de eventos. Es una característica muy interesante en términos del desarrollo de aplicaciones en tiempo real.

5 Objetivos 1. Reducir al mínimo el acoplamiento entre las clases a las que pertenecen los objetos subjects y observers para aumentar la reusabilidad de dichas clases. Para ello se usa las clases abstractas Subject y Observer, que crean un primer nivel de abstracción en el que se incluyen todas las dependencias entre clases para que las clases concretas que heredan de ellas sean lo más independientes posibles. 2. Permitir un número ilimitado de objetos observers que observen a un cierto objeto subject. Para ello la clase abstracta Subject tiene una lista de objetos observers a los que notificar en caso de que suceda algún evento de interés.

6 Diagrama de clases UML para el patrón Observer básico

7 Diagrama de clases UML para el patrón Observer básico
Subject: notificador de eventos. Observer: observador de eventos. En el diagrama se presuponen varias condiciones: Existe un único evento de interés (que el estado de un objeto subject cambie). La tarea que llevan a cabo los objetos observers cuando sucede ese evento de interés es actualizar su estado con el estado actual del objeto subject que observan. Cada objeto observer observa a un único objeto subject. Son los objetos subject los responsables de enviarse así mismos el mensaje notify() cuando cambian sus estados (y no son responsables los objetos observers cuando modifican el estado de su objeto subject).

8 Diagrama de clases UML para el patrón Observer básico
El funcionamiento básico es: 1. Algún objeto modifica el estado de un objeto ConcreteSubject enviando el mensaje setState() a dicho objeto (se produce un evento de interés). 2. El objeto ConcreteSubject cambia su estado y se envía a sí mismo el mensaje notify(), con lo que notifica a todos los objetos observers de su lista (a todos los que le observan) enviándoles el mensaje update(). 3. Los objetos notificados serán de una clase ConcreteObserver que hereda de Observer. Al recibir el mensaje update(), consultarán el estado del objeto ConcreteSubject que les envió la notificación (enviándole el mensaje getState()) y actualizarán su propio estado con el resultado obtenido (los objetos observers llevan a cabo la tarea correspondiente al evento de interés que se ha producido).

9 Diagrama de clases UML para el patrón Observer básico
Cuando el evento es lanzado cada observador recibe una callback. Cuando un observador concreto es informado de un cambio en el sujeto concreto, éste puede pedirle al sujeto más información que será usada para actualizar su estado.

10 Patrón Observer: aplicabilidad
Una abstracción tiene dos aspectos y uno depende del otro. (Encapsular estos aspectos en objetos separados permite modificarlos y reutilizarlos de forma independiente) Un cambio en un objeto requiere cambiar otros, y no sabemos cuántos objetos necesitan cambiarse. Un objeto debería ser capaz de notificar a otros sin hacer suposiciones sobre quiénes son dichos objetos. Es decir no queremos que los objetos estén fuertemente acoplados.

11 Ventajas y desventajas del patrón Observer básico
Permite modificar las clases subjects y las observers independientemente. Se pueden rehusar clases subjects sin rehusar sus clases observers. Permite añadir nuevas clases observers a una clase subject que ya tenía asociadas unas clases observers sin modificar la clase subject o alguno de esas clases observers que ya tenía. Permite que dos capas de abstracción de diferentes niveles de abstracción se puedan comunicar entre sí sin romper esa división en capas de abstracción. Por ejemplo, en el caso de las capas de Presentación y Dominio. Permite comunicación broadcast, es decir, un objeto subject envía su notificación a todos los objetos observers que lo estén observando sin enviárselo a ningún observer en concreto (el mensaje no tiene un destinatario concreto). Todos los observers reciben el mensaje y deciden si hacerle caso ó ignorarlo.

12 Ventajas y desventajas del patrón Observer básico
El protocolo de comunicación entre los objetos subject y sus objetos observers es muy pobre: el evento siempre es que se ha producido algún cambio en el estado del objeto subject, el mensaje no indica el destinatario (siempre es broadcast) y tampoco indica qué es lo que ha cambiado en el objeto subject (y, entonces, son sus objetos observers los que tienen que deducir qué es lo que ha cambiado en el objeto subject sin ayuda de éste, si así lo desean; lo que puede introducir gran complejidad computacional en los observers). Aumenta el número de clases necesarias para implementar la aplicación y disminuye la comprensibilidad de ésta. Los observers dependen del subject al que observan, pues lo conocen (hacen referencia a él), por lo que cambios en la clase del subject pueden provocar cambios en las de los observers.

13 Notas de implementación
Si los objetos observers pueden observar a varios objetos subject a la vez, es necesario ampliar el servicio update() para permitir conocer a un objeto observer dado cuál de los objetos subject que observa le ha enviado el mensaje de notificación. Una forma de implementarlo es añadiendo un parámetro al servicio update() que sea el objeto subject que envía la notificación (el remitente). Y añadir una lista de objetos subject observados por el objeto observer en la clase Observer. Hay dos opciones en cuanto a qué objeto invoca el servicio notify(): El objeto subject: todos los servicios de la clase Subject que modifican el estado del objeto subject envían el mensaje notify() reflexivamente (patrón Observer básico). Ventaja: Los observers no tienen que recordar invocar a notify() cuando modifican el estado de un objeto subject. Desventaja: sucesivos cambios de estado de un objeto subject provocan sucesivas llamadas a notify(), lo que puede ser ineficiente. El objeto observer: decide cuándo es necesario enviar el mensaje notify() a su objeto subject y se lo envía en ese momento. Ventaja: Los objetos observers deciden cuándo invocar a notify(), permitiendo realizar sucesivos cambios en el estado de un objeto subject y realizando un única invocación a notify() al final, lo que es más eficiente. Desventaja: Los observers tienen la responsabilidad de invocar a notify(), por lo que tienen que recordar hacerlo. Si los objetos observers observan varios eventos de interés que pueden suceder con los objetos subjects, es necesario ampliar el servicio add() y el update() además de la implementación del mapeo subject-observers en la clase abstracta Subject (que tiene que incluir la información de qué evento está observando cada observer). Una forma de implementarlo consiste en introducir un nuevo parámetro al servicio add() que indique el evento de interés del observer a añadir e introducirlo también como un nuevo parámetro en el servicio update() para que el subject que reciba el mensaje de notificación sepa qué evento ha ocurrido de los que observa.

14 Clases en la API de Java para implementar el Patrón Observer
Interfaz Observer public interface Observer Una clase puede implementar la interfaz Observer cuando dicha clase quiera ser informada de los cambios que se produzcan en los objetos observados. Tiene un servicio que es el siguiente: void update (Observable o, Object arg) Este servicio es llamado cuando el objeto observado es modificado.

15 Clases en la API de Java para implementar el Patrón Observer
Class Observable public Class Observable extends Object Esta clase representa un objeto Subject, o “dato” en el modelo vista. Constructor: Observable () : construye un objeto Subject con cero Observers.

16 Clases en la API de Java para implementar el Patrón Observer
Nos ofrece los siguientes servicios: void addObserver (Observer o) protected void clearChanged() int countObservers() void deleteObserver (Observer o) void deleteObservers() boolean hasChanged() void notifyObservers() void notifyObservers (Object arg) protected void setChanged()

17 Ejemplo Se trata de una aplicación que almacena una serie de datos, tres números enteros (a, b y c), y los representa en pantalla.

18 Ejemplo (diagrama de clases UML con el patrón Observer básico)

19 Ejemplo (código Java) public abstract class Subject {
private List<Observer> observers; public void add(Observer o) this.observers.add(o); } public void remove(Observer o) this.observers.remove(o); public void notify() for (int i = 0; i<this.observers.size(); i++) this.observers.get(i).update(); public Subject() this.observers = new ArrayList<Observer>(); public abstract class Observer { private Subject subject; protected Subject getSubejct() return this.subject; } public Observer(Subject s) this.subject = s; public abstract void update();

20 Ejemplo (código Java) public class Dominio extends Subject {
private double a, b, c; public Dominio(double[3] s) super(); this.a = s[0]; this.b = s[1]; this.c= s[2]; } public double[3] getState() double[3] s = new double[3]; s[0] = this.a; s[1] = this.b; s[2] = this.c; return s; public void setState(double[3] s) this.notify(); public class Vista1 extends Observer { private double[][] tabla = new double[3][3]; private int sig = 0; public Vista1(Dominio d) super(d); this.update(); } public void update() double[3] s = ((Dominio).getSubject()).getState(); this.tabla[sig] = s; sig = (sig+1)%3; this.redibujar();

21 Ejemplo (código Java) public class Vista2 extends Observer {
private double a, b, c; public Vista2(Dominio d) super(d); this.update(); } public void update() double[3] s = ((Dominio)getSubject()).getState(); a = s[0]; b = s[1]; c = s[2]; this.redibujar(); public class Vista3 extends Observer { private double a, b, c; public Vista3(Dominio d) super(d); this.update(); } public void update() double[3] s = ((Dominio)getSubject()).getState(); a = s[0]; b = s[1]; c = s[2]; this.redibujar();

22 Patrones Relacionados
Se pueden encapsular semánticas complejas entre subjects y observers mediante el patrón Mediator. Dicha encapsulación podría ser única y globalmente accesible si se usa el patrón Singleton.


Descargar ppt "Patrones de Comportamiento: Patrón de Diseño Observer"

Presentaciones similares


Anuncios Google