为什么在通知观察者之前需要调用setChanged?

时间:2013-02-27 19:51:42

标签: java

我最近读过Java的Observable课程。我不明白的是:在通知观察者之前(notifyObservers())我必须调用setChanged()。 notifyObservers方法中有一个布尔值,要求我们调用setChanged。布尔值的目的是什么?为什么我必须调用setChanged()?

5 个答案:

答案 0 :(得分:26)

在长时间的治疗中,您可以多次拨打setChanged(),但最后只能拨打一次notifyObservers()。如果在结束之前,出于内部原因,您决定回滚,则可以选择致电clearChanged()。在后一种情况下,notifyObservers()无效。

答案 1 :(得分:1)

setchanged()用作更改状态的指示或标志。如果为true,则notifyObservers()可以运行并更新所有观察者。如果为false,则调用notifyObservers()而不调用setchanged(),并且不会通知观察者。

答案 2 :(得分:1)

可能的原因可能是setChanged()有一个受保护的修饰符。同时,即使是观察者也可以在任何地方调用notifyObservers()。从那以后,可观察者和观察者可以通过这种机制相互作用。

答案 3 :(得分:1)

setChanged()

  

将此Observable对象标记为已更改; hasChanged   方法现在将返回true。

notifyObservers()
  

如果此对象已更改(如hasChanged方法所示),则通知其所有观察者,然后调用clearChanged方法以指示此对象不再更改。

基本上,您使用setChanged()通知观察者超类已发生更改。然后你调用notifyObservers()方法来启动,告诉观察者改变了什么。

setChanged()因为它允许类在通过调用clearChanged()通知观察者之前撤消更改。 如果你没有setChanged()标志,那么你基本上是在通知观察者,并且没有检测到任何变化,因此他们不会响应“通知”。

请参阅我的代码以获得更多解释:

主要方法     公共类SpeedRunner {

public static void main(String[] args) {
    SpeedMonitor monitor = new SpeedMonitor();
    // Create a speedometer and register the monitor to it...
    SpedoMeter speedo = new SpedoMeter();
    speedo.addObserver(monitor);
    // Drive at different speeds...
    speedo.setCurrentSpeed(50);
    speedo.setCurrentSpeed(70);
    speedo.setCurrentSpeed(40);
    speedo.setCurrentSpeed(100);
    speedo.setCurrentSpeed(69);
}

观察者(当有趣的事情发生时通知的对象):

//this is the observer since it is observing changes in the speedo.
public class SpeedMonitor implements Observer {
public static final int SPEED_TO_ALERT = 70;

public void update(Observable obs, Object obj) {
    SpedoMeter speedo = (SpedoMeter) obs;
    if (speedo.getCurrentSpeed() > SPEED_TO_ALERT) {
        System.out.println("** ALERT ** Driving too fast! (" + speedo.getCurrentSpeed() + ")");
    } else {
        System.out.println("... nice and steady ... (" + 
        speedo.getCurrentSpeed() + ")");
        }
    }
}

主题(感兴趣的对象)

public class SpedoMeter extends Observable{
private int currentSpeed;

public SpedoMeter(){
    currentSpeed = 0;
}

public void setCurrentSpeed(int speed){
    currentSpeed = speed;

//        setChanged();
    notifyObservers();
}

        public int getCurrentSpeed() {
        return currentSpeed;
    }

}

注释掉setChanged(),你会发现观察者没有任何东西被拾取,因此控制台是空的。

请参阅此教科书。它非常适合学习设计模式。

  贝维斯,托尼。 Java Design Pattern Essentials(Kindle Location 1835)。   Ability First Limited。 Kindle版。

答案 4 :(得分:0)

public void notifyObservers(Object arg) {
    /*
     * a temporary array buffer, used as a snapshot of the state of
     * current Observers.
     */
    Observer[] arrLocal;

    synchronized (this) {
        /* We don't want the Observer doing callbacks into
         * arbitrary Observables while holding its own Monitor.
         * The code where we extract each Observable from
         * the ArrayList and store the state of the Observer
         * needs synchronization, but notifying observers
         * does not (should not).  The worst result of any
         * potential race-condition here is that:
         *
         * 1) a newly-added Observer will miss a
         *   notification in progress
         * 2) a recently unregistered Observer will be
         *   wrongly notified when it doesn't care
         */
        if (!hasChanged())
            return;

        arrLocal = observers.toArray(new Observer[observers.size()]);
        clearChanged();
    }

    for (int i = arrLocal.length-1; i>=0; i--)
        arrLocal[i].update(this, arg);
}

评论是

的原因