`
liushuoboco
  • 浏览: 707 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Observable与Observer

 
阅读更多
在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。例如在文档/视图结构中,文档被修改了,视图就会得到通知。

      java.util.Observable中有两个方法对Observer特别重要,一个是setChange()方法用来设置一个内部标志位注明数据发生了变化;一个是notifyObservers()方法会去调用一个列表中所有的Observer的update()方法,通知它们数据发生了变化。
      Observer通过Observable的addObserver()方法把自己添加到这个列表中。这个列表虽然由Observable拥有,但Observable并不知道到底有哪些Observer正在观察等待通知。Observable只提供一个方法让Observer能把自己添加进列表,并保证会去通知Observer发生了变化。通过这种机制,可以有任意多个Observer对Observable进行观察,而不影响Observable的实现。

一个简单例子:
import java.util.Observable;

public class SimpleObservable extends Observable
{
   private int data = 0;

   public int getData(){
       return data;
   }

   public void setData(int i){
       if(this.data != i){ this.data = i; setChange();}
          notifyObservers();
         //只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
       }
   }
}

import java.util.Observable;
import java.util.Observer;

public class SimpleObserver implements Observer
{
   public SimpleObserver(SimpleObservable so){
      so.addObserver(this );
   }

   public void update(Observable o,Object arg/*任意对象,用于传递参数*/){
      System.out.println(“Data has changed to” + (SimpleObservable)o.getData());
   }
}

public class SimpleTest
{
   public static void main(String[] args){
      SimpleObservable doc = new SimpleObservable ();
      SimpleObserver view = new SimpleObserver (doc);
      doc.setData(1);
      doc.setData(2);
      doc.setData(2);
      doc.setData(3);
   }
}

Data has changed to 1
Data has changed to 2  //第二次setData(2)时由于没有setChange,所以update没被调用
Data has changed to 3

      Observable类有两个私有变量。一个boolean型的标志位,setChange()将它设为真,只有它为真时,notifyObservers方法才会调用Observer的update方法,clearChange()设标志位为假,hasChange返回当前标志位的值。另一个是一个Vector,保存着一个所有要通知的Observer列表,addObserver添加Observer到列表,deleteObserver从列表中删除指定Observer,deleteObservers清空列表,countObservers返回列表中Observer的数目,在Observer对象销毁前一定要用deleteObserver将其从列表中删除,不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。  
      Observable的所有方法都是同步的,保证了在一个线程对其标志位、列表进行操作时,不会有其它线程也在操作它。
      Observable的notifyObservers(Object obj)形式可以再调用update时将参数传进去。
通知顺序通常时越晚加入列表的越先通知。update会被依次调用,由于一个update返回后下一个update才被调用,这样当update中有大量操作时,最好将其中的工作拿到另一个线程或者Observer本身同时也是一个Thread类,Observer先挂起,在update中被唤醒,这样会有一个隐患,Observer线程还没来得及挂起,update就被调用了,通知消息就这样被错过了,一种解决办法是在Observer中实现一个同步的队列结构,并有一个类来封装参数,update实现一个参数类的对象把接收到的通知消息的参数封装在里面,然后把其加进队列,run方法从队列中移除参数对象,并进行处理,这保证了没有通知信息被丢失。
    在多线程时,只有Observer会与单线程不同,Observable不需任何改变来支持多线程,因为它又很多作为单独线程运作的Observer。

一个多线程例子:
import java.util.*;

public class SimpleObserverEx extends Thread implements Observer
{
   Queue queue;//利用一个消息队列来接收Observable的通知,保证消息不会丢失

   public void run(){
      while(true){
         ArgPack a = (ArgPack) queue.dequeue();
         Observable o = a.o;
         Object obj = a.arg;
         //…执行相应的工作
      }
   }

   public void update(Observable o, Object arg){
      ArgPack a = new ArgPack (o,arg);
      queue.queue(a);
   }
}

import java.util.*;

public class Queue extends LinkedList{
   public synchronized void queue(Object o){
      addLast(o);
      notify();
   }

   public synchronized void dequeue(){
      while(this.isEmpty()){
         try{
            wait();
         }
         catch(InterruptedException el){
         }
      }
      Object o;
      try{
         o =this.removeFirst();
      }
      catch(NoSuchElementException){
         o = null;
      }
      return o;
   }
}

public class ArgPack
{
   public Observable o;
   public Object obj;
   public ArgPack (Observable o,Object obj){
      this.o = o;this.obj = obj;
   }
}

Observable是一个类而不是一个接口这限制了它的使用,一个解决的办法是在一个Observable类中把我们的类包装进去(把我们的类实例当作Observable的域),因为Observable中的setChange是一个protected方法,我们没法在外面调用它。所以没法在我们的类中包装一个Observable,但是如果我们的类中同样也有protected方法,那这个办法就无法使用
分享到:
评论

相关推荐

    observable-observer

    在Java中,`Observable`类和`Observer`接口是内置的实现,用于创建这种观察者模式。现在我们来详细探讨`Observable`和`Observer`的原理以及如何手动实现简单的`MyObservable`和`MyObserver`。 首先,`Observable`类...

    android实现单指拖动放大缩小图片

    在这个工程中,`Observable与Observer`模式被巧妙地应用来实现实时的图片操作反馈。接下来,我们将详细讨论如何通过这两个设计模式来实现这一功能,并结合具体的技术细节进行深入探讨。 首先,`Observable与...

    java实现观察者模式-Java内置的观察者模式(基于Observable和Observer)

    Java内置的Observable类和Observer接口提供了基本的观察者模式功能,你可以通过继承Observable类和实现Observer接口来使用

    Java观察者设计模式(Observable和Observer)

    在Java中,观察者模式通过`java.util.Observable`类和`java.util.Observer`接口得以实现。 一、观察者模式介绍 观察者模式的核心在于建立一种对象间的依赖关系,这种关系使得当一个对象(被观察者)的状态发生改变...

    RxSwift Reactive Programming with Swift

    Observable与Observer** Observable是RxSwift中的核心组件,它可以是任何类型的数据流,如用户输入、网络请求的结果或者定时器触发的事件。Observer则订阅Observable,监听并处理Observable发出的事件。在Swift中,...

    Android开发丶使用RxJava来完成自动轮播图

    接下来,我们需要将Observable与Observer关联起来,即订阅Observable: ```java timerObservable.subscribe(observer); ``` 至此,轮播图的基本框架已经搭建完成。但为了实现更高级的功能,如添加滑动切换、点击...

    rxjava essentials

    - **Subject**:既是一个Observable也是一个Observer,能够将Observable与Observer的特性结合起来。 #### 响应式编程入门 - **RxAndroidUtils**:这是RxJava的一个扩展,专为Android平台设计,能够更好地集成...

    rxjava_for_android

    2. **Observable与Observer**:在RxJava中,`Observable`是发布者,负责产生数据;`Observer`是订阅者,负责接收和处理这些数据。通过`.subscribe()`方法,Observer可以订阅Observable,形成数据流。 3. **操作符**...

    Rxjava2学习demo

    - **Subscription(订阅)**:是Observable与Observer之间的桥梁,用于建立和管理两者之间的连接。 2. **操作符**: - **创建操作符**:如`just()`, `from()`, `range()`, `interval()`等,用于从各种数据源创建...

    Manning.RxJava for Android Developers.2019.pdf

    Observable与Observer** - **Observable(可观察者)**: 它是数据源或事件源,可以产生一系列的数据或事件。 - **Observer(观察者)**: 它负责接收来自Observable的数据或事件,并进行相应的处理。 **2. ...

    RxSwift.Reactive.Programming.with.Swift.v2.0.pdf

    - **Subscription**:订阅关系,连接Observable与Observer之间的桥梁。 通过订阅`Observable`,开发者可以指定某个`Observer`来接收特定类型的数据或事件。这种机制使得数据流动更加可控,也更易于理解和维护。 ##...

    Rxjava-中文文档

    3. Subscription(订阅): 表示Observable与Observer之间的连接。订阅操作会启动Observable,开始发出事件。 4. Operators(操作符): 用于组合、创建和过滤Observable发出的序列的方法,是RxJava中最为核心的部分...

    前端开源库-rxjs-es

    **二、Observable与Observer** 在 `RxJS` 中,`Observable` 是一个可以发出一系列值的对象,而`Observer` 是用来接收这些值的对象。通过订阅(subscribe)`Observable`,`Observer` 可以监听并处理 `Observable` ...

    mvp+retrofit+rxJava 简单demo

    - **Observable与Observer**:RxJava的核心是Observable(可观察者)和Observer(观察者)。Observable发出数据,Observer接收数据。 - **操作符**:RxJava提供了丰富的操作符,如map、filter、concatMap、flatMap...

    RxJavaDemo.rar

    3. 订阅:使用`.subscribe()`方法将Observable与Observer连接起来。Observer定义了如何处理接收到的数据或事件。 4. 错误处理:通过`onErrorResumeNext()`或`onErrorReturn()`等操作符可以优雅地处理错误,避免程序...

    Android-LearningRxJava(RxJava详解)

    Observable负责发布数据,Observer接收并处理这些数据,Subscription是Observable与Observer之间的桥梁,Operator则用于转换或操作数据流。 **二、Schedulers的使用** 1. **线程管理**:在Android中,UI操作必须在...

    RxAndroid学习demo自己写的经过实践的

    2. **Observable与Observer**:在RxAndroid中,`Observable`(可观察者)是数据的来源,它可以发出一系列的事件或数据。`Observer`(观察者)则负责订阅这些事件并作出响应。当`Observable`发出数据时,`Observer`会...

    MVC小例子 使用Java类库observer和Observable

    在"Java类库observer和Observable"的上下文中,`Observer`和`Observable`是Java标准库中的接口和类,它们实现了观察者模式,这是MVC模式中的一个重要组成部分。观察者模式允许一个对象(观察者)注册到另一个对象...

    AndroidProject,RXJava+改装.zip

    - **Subscription(订阅)**:建立Observable与Observer之间的连接,可以通过调用unsubscribe()方法取消订阅。 - **Operator(操作符)**:RXJava提供了丰富的操作符,如map()、filter()、concat()等,用于转换、...

Global site tag (gtag.js) - Google Analytics