2011-09-01 18 views
16

Estoy tratando de entender el Observador y el Observable.Observable en Java

He aquí un ejemplo que estoy tratando de averiguar:

public class IntegerDataBag extends Observable implements Iterable<Integer> { 

    private ArrayList<Integer> list= new ArrayList<Integer>(); 

    public void add(Integer i){ 
     list.add(i); 
     setChanged(); 
     notifyObservers(); 
    } 

    public Iterator<Integer> iterator(){ 
     return list.iterator(); 
    } 

    public Integer remove (int index){ 
     if (index< list.size()){ 
      Integer i = list.remove(index); 
      setChanged(); 
      notifyObservers(); 
      return i; 
     } 
     return null; 
    } 

} 

public class IntegerAdder implements Observer { 

    private IntegerDataBag bag; 

    public IntegerAdder(IntegerDataBag bag) { 
     this.bag = bag; 
     bag.addObserver(this); 
    } 

    public void update(Observable o, Object arg) { 
     if (o == bag) { 
      System.out.println("The contents of the IntegerDataBag have changed"); 
     } 
    } 

} 
  1. El bag.addObserver() se pueden hacer sólo porque IntegerDataBag extiende Observable?

  2. ¿Dónde se va a agregar este observador? ¿Qué se está creando y dónde?

  3. ¿Cuál es la diferencia entre setChanged() y notifyObservers()?

  4. No entiendo el método update; ¿Qué significa arg? ¿Por qué tengo que verificar que o==bag? ¿Por qué debería actualizar otro observable?

  5. ¿Por qué debería necesitar este observador de todos modos?

+0

Este es uno de los pocos patrones que solo se puede entender mejor cuando llega al punto en que * realmente * necesita usar uno en su proyecto existente. – BalusC

+0

Me gusta en MVC, por ejemplo. Pruebe este código: http://www.emilmont.net/doku.php?id=java:design_patterns:model_view_controller –

Respuesta

10
  1. Sí. addObserver es un método en la clase abstracta Observable. Consulte Observable en la documentación de Java.
  2. Se agrega a una lista en Observable.
  3. Una llamada al notifyObservers no hará nada hasta que se establezca setChanged.
  4. Puede tener múltiples Observables en la misma aplicación.
  5. Observer es un patrón de diseño común. El ejemplo habitual es cuando tienes un modelo y múltiples vistas. Cada vista es un observador en el modelo; si el Modelo cambia, las Vistas se actualizan.
+0

Desde la memoria, Observable es una clase asbtract y no solo una interfaz. También setChanged se usa como una bandera, creo. Esto es para evitar una actualización innecesaria. Los argumentos pueden usarse como un parámetro. Busque Listener ya que este enfoque también se usa en Java. –

+0

@James Poulson, Observable es ** no ** una clase abstracta en absoluto (en el JDK). –

+0

Tienes razón, en realidad es una clase normal/concreta. Como este artículo indica que esto difiere de la implementación de otros patrones de diseño que se basan en interfaces/clases de asbtract: http://www.javapractices.com/topic/TopicAction.do?Id=156 –

4

El bag.addObserver() se puede hacer sólo porque IntegerDataBag extiende observable?

Sí.

2. ¿A quién se está sumando este observador? ¿Qué se está creando y dónde?

En la clase observable relacionada, que su clase se está extendiendo.

4. No entiendo el método de actualización- ¿Qué significa args?

Se invoca cuando ha cambiado el estado de un objeto observado. The args es el parámetro pasado a nofityObserver.

y por qué necesito comprobar que o == bolsa, ¿por qué debería actualizar otra observable?

No es necesario que compruebe nada.

5.¿Por qué debería necesitar este observador de todos modos?

Es un patrón de diseño muy útil. Echa un vistazo a wikipedia article.

EDIT: echaba de menos puntos:

¿Cuál es la diferencia entre setChanged() y notifyObservers()?

setChanged() marca un objeto que indica que ha cambiado. notifyObservers es responsable de despertar a todos los observadores que escuchan el objeto observable.

2

En respuesta a sus puntos.

  1. Si estás en lo correcto

  2. Se añade el observador en una lista mantenida en el objeto observable

  3. es necesario llamar a setChanged() antes de que notifique a los observadores, de lo contrario, ganaron' Sé que el objeto ha cambiado. Una vez que llame a notifyObservers(), todos los obvserers son notificados del cambio. Si no llamas a setChanged primero, tus observadores no serán notificados.

  4. arg es algo que le gustaría pasar a los observadores cuando llama a notifyObservers (arg);

3

El bag.addObserver() se puede hacer sólo porque IntegerDataBag extiende observable?

Sí, el método addObserver se implementa en Observable.

¿Dónde está este observador se agrega? ¿Qué se está creando y dónde? se añade

El observador a una lista de observadores que se declaran en Observable como privada, por lo que no es visible en la subclase.

¿Cuál es la diferencia entre setChanged() y notifyObservers()?

Cuando llama al notifyObservers() sin llamar primero al , no se realizan notificaciones.

No entiendo el método de actualización- ¿Qué significa args? y ¿por qué necesito verificar esa o == bolsa, ¿por qué actualizaría otra observable?

Uno Observer puede ver varios Observables. Al examinar el primer parámetro del método update, puede averiguar qué observador le está notificando algo.

¿Por qué debería necesitar este observador de todos modos?

Cada vez que desee que una clase envíe eventos a otras clases pero no desea una dependencia directa de esa clase en sus observadores.

2

El patrón de observador es similar al concepto de oyentes. El objeto que se está escuchando mantiene un registro de todos sus oyentes. Por ejemplo, una clase de stock stock puede permitir que los objetos escuchen un determinado evento, como que el nivel de existencias caiga por debajo del nivel de advertencia.

Desde el punto de vista del observador:

llamada subscribe() o addEventListener() o similares. El observador es entonces "notificado" cuando el evento realmente ocurre, usualmente llamando a una función en el observador (la función del manejador de eventos).

desde el punto de vista de observables:

objetos que deseen observar el objeto observable registrar su interés mediante una llamada al subscribe() o addEventListener() que el anterior. Lo observable agrega estos observadores a una matriz, lista o alguna otra estructura de datos.

Una vez que ocurre realmente el evento, se notifica a los oyentes llamando a la función del controlador de eventos en la clase de los observadores.

6

Tomemos un ejemplo práctico para el patrón Observer: Twitter. Con Twitter podemos seguir otras personas y leer lo que publiquen casi en tiempo real.

Cada usuario de twitter es observable. Puedes agregarte como oyente ("Seguidor") y leer sus publicaciones. Cada usuario de Twitter hará un "notificar a los seguidores" (notifyObservers).

Aquí hacemos lo mismo. La clase IntegerDataBag tiene la capacidad de notificar a otras clases cada vez que se agrega o elimina un valor de su bolsa interna. Cualquier instancia (que implemente Observer) puede registrarse en un IntegerDataBag y recibirá mensajes a través del método de devolución de llamada (update).

En resumen, hacemos lo siguiente:

  1. Un observador (oyente, IntegerAdder) se agrega a una observables (IntegerDataBag)
  2. Algo sucede en el observables y la observable notifica a observadores
  3. El observables llamará a los métodos de devolución de llamada de todos los observadores reales
  4. El observador ahora ha sido notificada del evento y puede utilizarse

Esperanza, esta breve descripción ayuda en la comprensión de este patrón.


publicación/suscripción es un patrón similar: un editor es como un observable, un suscriptor como un observador. Y otro ejemplo práctico: uno puede suscribirse a un periódico y el editor lo enviará hasta que cancele su suscripción.

+0

+1 Gran respuesta, muchas gracias. – Numerator

+0

¿Y cuál es la diferencia entre el patrón Observable/Observer y Publis/Subscriber? –

2

El Observable llama al método update(). Este método se invoca llamando a notifyObservers(), que recorre todos los observadores y las llamadas actualizan sobre ellos. Esto informa al observador que el objeto que están viendo ha cambiado y que se puede realizar una determinada acción. El objeto args es lo que quieras que sea, también puede ser nulo, pero se puede utilizar para informar a los observadores qué tipo de actualización acaba de ocurrir.

5

El bag.addObserver() se puede hacer sólo porque IntegerDataBag extiende observable?

correcta, Observable es una clase que tiene el método addObserver().

¿Dónde está este observador se agrega? ¿Qué se está creando y dónde?

La clase Observer contiene una List o Vector (en la fuente JDK) de Observable objetos.

private Vector obs; 

Ahí es donde está almacenado.

¿Cuál es la diferencia entre setChanged() y notifyObservers()?

El setChanged() simplemente se cambia la marca Observable. El notifyObservers() simplemente llama a todos los observadores que tiene en la lista al update() (pasando un objeto cambiado al Observer) solo si el setChanged está establecido en verdadero.

No entiendo el método de actualización- ¿Qué significa args? y ¿por qué necesito verificar que o == bolsa, por qué debería actualizar otra observable?

El método update() cuenta la Observer que necesita actualización basada en la obj cambiado que recibe. Esto se llama por el notifyObservers() desde Observable.

¿Por qué debería necesitar este observador de todos modos?

Para crear un Listener para el evento impulsado escenario, es decir, si desea ser informado en el cambio de los objetos observables, entonces se necesita Observador.

Lea: GoF - Observer pattern.

2

El bag.addObserver() se puede realizar solo porque IntegerDataBag extends Observable?

Sí, ese es el punto.

¿Dónde está este observador se agrega? ¿Qué se está creando y dónde?

Agrega IntegerAdder a la lista de clases que observan IntegerDatabag para ver los cambios. A partir de ahora, si se produce un cambio en IntegerDataBag, notificará IntegerAdder a través del método notifyObservers(), que activará su método update().

¿Cuál es la diferencia entre setChanged() y notifyObservers()?

notifyObservers() llama al método de todos los observadores de la observables update(), y se usa para transmitir informaciones a este método. En cuanto a setChanged(), marca su objeto como "cambiado" para que el método hasChanged() ahora devuelva verdadero ... Se usa para monitorear los cambios en su clase observable.

No entiendo el método de actualización- ¿Qué significa args?

El método update() se hereda de la implementación de la interfaz del observador. Tiene que implementarlo. El Object arg es un argumento opcional que puede pasar al método a través del notifyObservers().

¿Por qué tengo que comprobar que o == bolsa, ¿por qué debería actualizar otra observable?

Dado que un observador puede "observar" más de un "observable", es necesario comprobar que es realmente IntegerDatabag que desencadenó update(), por lo tanto, o==bag.

¿Por qué debería necesitar este observador de todos modos?

Necesita el observador para controlar IntegerDataBag para ver los cambios. En su caso, imprime un mensaje en la consola cuando se modifica IntegerDatabag. El propósito del modelo Observer/Observable es específicamente monitorear los cambios en objetos específicos, y luego actualizar el programa en función de los cambios.

Cuestiones relacionadas