用Java观察

我正在尝试理解Observer和Observable。

这是我想要弄清楚的一个例子:

public class IntegerDataBag extends Observable implements Iterable { private ArrayList list= new ArrayList(); public void add(Integer i){ list.add(i); setChanged(); notifyObservers(); } public Iterator 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. bag.addObserver()只能因IntegerDataBag扩展Observable

  2. 这个观察者在哪里被添加? 什么是创造和在哪里?

  3. setChanged()notifyObservers()什么区别?

  4. 我不明白update方法; arg代表什么? 为什么我需要检查o==bag ? 为什么我要更新另一个observable?

  5. 为什么我还需要这个观察者呢?

  1. 是。 addObserverObservable抽象类中的一个方法。 请参阅Java文档中的Observable 。
  2. 它被添加到Observable的列表中。
  3. 在设置setChanged之前,对notifyObservers的调用将不执行任何setChanged
  4. 您可能在同一个应用程序中有多个Observable。
  5. Observer是一种常见的设计模式。 通常的例子是你有一个模型和多个视图。 每个视图都是模型的观察者; 如果模型更改,则视图会更新。

让我们来看一个Observer模式的实例:Twitter。 通过推特,我们可以关注其他人并阅读他们近乎实时发布的内容。

每个Twitter用户都是可观察的 。 您可以将自己添加为听众(“追随者”)并阅读他/她的post。 每个Twitter用户都会做一个“通知关注者”( notifyObservers )。

在这里我们也这样做。 只要在内部包中添加或删除值, IntegerDataBag类就能够通知其他类。 任何实例(实现Observer )都可以将自己注册到IntegerDataBag并通过它的回调方法( update )接收消息。

简而言之,我们执行以下操作:

  1. 观察者 (侦听器, IntegerDataBag )将自身添加到observableIntegerDataBag
  2. 观察者身上发生了一些事情, 观察者会通知观察者
  3. observable将调用所有实际观察者的回调方法
  4. 观察员现已收到有关该事件的通知,并可以使用它

希望,这个简短的描述有助于理解这种模式。


发布/订阅是一种类似的模式:发布者就像一个观察者,一个像观察者一样的订阅者。 另一个实际例子:一个人可以订阅一份报纸,发行人会发送报纸,直到你取消订阅。

bag.addObserver()只能因IntegerDataBag扩展Observable而生成?

Correct, Observable是一个具有addObserver()方法的类。

这个观察者在哪里被添加? 创造什么,在哪里?

Observer类包含Observable对象的ListVector (在JDK源中)。

 private Vector obs; 

这就是它存储的地方。

setChanged()notifyObservers()之间有什么不同?

setChanged()只标记Observable已更改。 只有当setChanged设置为true时, notifyObservers()才会调用列表中的所有观察者来update() (将更改的对象传递给Observer)。

我不明白更新方法 – args代表什么? 为什么我需要检查o == bag,为什么我要更新另一个observable?

update()方法告诉Observer它需要根据收到的更改的obj进行更新。 这是由ObservablenotifyObservers()调用的。

为什么我还需要这个观察者呢?

要为事件驱动的场景创建一个Listener ,即如果希望在更改可观察对象时获得通知,则需要Observer。

阅读:GoF – 观察者模式 。

bag.addObserver()只能因IntegerDataBag扩展Observable而生成?

是。

2.这个观察者被添加到哪里? 创造什么,在哪里?

进入相关的Observable类,您的类正在扩展。

4.我不了解更新方法 – args代表什么?

当观察对象的状态发生变化时调用它。 args是传递给nofityObserver的参数。

为什么我需要检查o == bag,为什么我要更新另一个observable?

你不需要检查任何东西。

为什么我还需要这个观察者?

这是一个非常有用的设计模式。 看看维基百科的文章 。

编辑:我错过了一点:

setChanged()和notifyObservers()之间有什么不同?

setChanged()标记一个对象,表示它已更改。 notifyObservers负责唤醒监听可观察对象的所有观察者。

bag.addObserver()只能因IntegerDataBag扩展Observable而生成?

是的, addObserver方法在Observable实现。

这个观察者在哪里被添加? 创造什么,在哪里?

观察者被添加到观察者列表中,这些观察者在Observable声明为private,因此它在您的子类中不可见。

setChanged()和notifyObservers()之间有什么不同?

在没有先调用setChanged() notifyObservers()情况下调用notifyObservers() setChanged() ,不会发生通知。

我不明白更新方法 – args代表什么? 为什么我需要检查o == bag,为什么我要更新另一个observable?

One Observer可以观看多个Observables 。 通过检查update方法的第一个参数,您可以确定哪个观察者正在通知您某些事情。

为什么我还需要这个观察者呢?

任何时候你希望一个类将事件发送到其他类,但你不希望它的观察者从该类直接依赖。

回答你的观点。

  1. 是的,你是对的

  2. 观察者被添加到Observable对象中维护的列表中

  3. 您需要在通知观察者之前调用setChanged(),否则他们将不知道对象已更改。 一旦调用notifyObservers(),所有obvserers都会收到有关更改的通知。 如果您不首先调用setChanged,则不会通知您的观察者。

  4. 当你调用notifyObservers(arg)时,arg是你想要传递给Observers的东西;

观察者模式类似于听众的概念。 正在收听的对象维护着所有听众的记录。 例如,股票监控类可以允许对象监听某个事件,例如股票水平低于警告水平。

从观察者的角度来看:

调用subscribe()addEventListener()等。 然后,当事件实际发生时,通常通过调用观察者中的函数(事件处理函数)来“通知”观察者。

从观察者的角度来看:

希望观察可观察对象的对象通过调用上述的subscribe()addEventListener()来注册它们的兴趣。 因此,observable将这些观察者添加到数组,列表或其他一些数据结构中。

事件实际发生后,通过调用观察者类中的事件处理函数来通知侦听器。

observable调用update()方法。 通过调用notifyObservers()来调用此方法,该函数通过所有Observers进行迭代并对它们调用update。 这通知观察者他们正在观看的对象已经改变并且可以执行某个动作。 args对象是你想要的任何东西,它也可以是null,但它可以用来通知观察者刚刚发生了什么类型的更新。

bag.addObserver()只能因IntegerDataBag扩展Observable而生成?

是的,这就是重点。

这个观察者在哪里被添加? 什么是创造和在哪里?

它将IntegerDatabag添加到观察IntegerDatabag以进行更改的类列表中。 从现在开始,如果IntegerDataBag发生IntegerDataBag ,它将通过notifyObservers()方法通知IntegerDataBag ,这将触发其update()方法。

setChanged()和notifyObservers()有什么区别?

notifyObservers()调用observable的每个观察者的update()方法,并用于将信息传递给此方法。 对于setChanged() ,它将您的对象标记为“已更改”,以便hasChanged()方法现在将返回true …它用于监视对可观察类的更改。

我不明白更新方法 – args代表什么?

update()方法inheritance自observer接口的实现 – 您必须实现它。 Object arg是一个可选参数,您可以通过notifyObservers()传递给该方法。

为什么我需要检查o == bag,为什么我要更新另一个observable?

由于观察者可以“观察”多个“可观察”,你需要检查它是否真的是IntegerDatabag触发了update() ,因此o==bag

为什么我还需要这个观察者呢?

您需要观察者监视IntegerDataBag以进行更改。 在您的情况下,在修改IntegerDatabag时在控制台中打印消息。 Observer / Observable模型的目的是专门监视特定对象的更改,然后根据更改更新程序。