用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"); } } }
-
bag.addObserver()
只能因IntegerDataBag
扩展Observable
? -
这个观察者在哪里被添加? 什么是创造和在哪里?
-
setChanged()
和notifyObservers()
什么区别? -
我不明白
update
方法;arg
代表什么? 为什么我需要检查o==bag
? 为什么我要更新另一个observable? -
为什么我还需要这个观察者呢?
- 是。
addObserver
是Observable
抽象类中的一个方法。 请参阅Java文档中的Observable 。 - 它被添加到
Observable
的列表中。 - 在设置
setChanged
之前,对notifyObservers
的调用将不执行任何setChanged
。 - 您可能在同一个应用程序中有多个Observable。
-
Observer
是一种常见的设计模式。 通常的例子是你有一个模型和多个视图。 每个视图都是模型的观察者; 如果模型更改,则视图会更新。
让我们来看一个Observer模式的实例:Twitter。 通过推特,我们可以关注其他人并阅读他们近乎实时发布的内容。
每个Twitter用户都是可观察的 。 您可以将自己添加为听众(“追随者”)并阅读他/她的post。 每个Twitter用户都会做一个“通知关注者”( notifyObservers
)。
在这里我们也这样做。 只要在内部包中添加或删除值, IntegerDataBag
类就能够通知其他类。 任何实例(实现Observer
)都可以将自己注册到IntegerDataBag
并通过它的回调方法( update
)接收消息。
简而言之,我们执行以下操作:
- 观察者 (侦听器,
IntegerDataBag
)将自身添加到observable (IntegerDataBag
) - 在观察者身上发生了一些事情, 观察者会通知观察者
- observable将调用所有实际观察者的回调方法
- 观察员现已收到有关该事件的通知,并可以使用它
希望,这个简短的描述有助于理解这种模式。
发布/订阅是一种类似的模式:发布者就像一个观察者,一个像观察者一样的订阅者。 另一个实际例子:一个人可以订阅一份报纸,发行人会发送报纸,直到你取消订阅。
bag.addObserver()只能因IntegerDataBag扩展Observable而生成?
Correct, Observable
是一个具有addObserver()
方法的类。
这个观察者在哪里被添加? 创造什么,在哪里?
Observer
类包含Observable
对象的List
或Vector
(在JDK源中)。
private Vector obs;
这就是它存储的地方。
setChanged()
和notifyObservers()
之间有什么不同?
setChanged()
只标记Observable
已更改。 只有当setChanged
设置为true时, notifyObservers()
才会调用列表中的所有观察者来update()
(将更改的对象传递给Observer)。
我不明白更新方法 – args代表什么? 为什么我需要检查o == bag,为什么我要更新另一个observable?
update()
方法告诉Observer
它需要根据收到的更改的obj
进行更新。 这是由Observable
的notifyObservers()
调用的。
为什么我还需要这个观察者呢?
要为事件驱动的场景创建一个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
方法的第一个参数,您可以确定哪个观察者正在通知您某些事情。
为什么我还需要这个观察者呢?
任何时候你希望一个类将事件发送到其他类,但你不希望它的观察者从该类直接依赖。
回答你的观点。
-
是的,你是对的
-
观察者被添加到Observable对象中维护的列表中
-
您需要在通知观察者之前调用setChanged(),否则他们将不知道对象已更改。 一旦调用notifyObservers(),所有obvserers都会收到有关更改的通知。 如果您不首先调用setChanged,则不会通知您的观察者。
-
当你调用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模型的目的是专门监视特定对象的更改,然后根据更改更新程序。