开发者

Observable in Java

I'm trying to understand the Observer and the Observable.

Here's an example that I'm trying to figure out:

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) {
 开发者_C百科       if (o == bag) {
            System.out.println("The contents of the IntegerDataBag have changed");
        }
    }

}
  1. The bag.addObserver() can be made only because IntegerDataBag extends Observable?

  2. Where is this observer being add to? What is being created and where?

  3. What is the difference between setChanged() and notifyObservers()?

  4. I don't understand the update method; what does arg stand for? Why do I need to check that o==bag? Why would I update another observable?

  5. Why should I need this observer anyway?


  1. Yes. addObserver is a method in the Observable abstract class. See Observable in the Java documentation.
  2. It is added to a list in Observable.
  3. A call to notifyObservers will do nothing until setChanged is set.
  4. You might have multiple Observables in the same application.
  5. Observer is a common design pattern. The usual example is when you have a Model and multiple Views. Each View is an Observer on the Model; if the Model changes, the Views get updated.


Let's take a practical example for Observer pattern: Twitter. With Twitter we can follow some other people and read whatever they post in near realtime.

Every twitter user is observable. You can add yourself as a listener ("Follower") and read his/her posts. Every twitter user will do a "notify Followers" (notifyObservers).

Here we do the same. The class IntegerDataBag has the capability to notify other classes whenever a value is added to or deleted from it's internal bag. Any instance (that implements Observer) can register itself to an IntegerDataBag and will receive messages through it's callback method (update).

In short, we do the following:

  1. A observer (listener, IntegerAdder) adds itself to an observable (IntegerDataBag)
  2. Something happens at the observable and the observable notifies its observers
  3. The observable will call the callback methods of all actual observers
  4. The observer now has been notified of the event and can use it

Hope, this short description helps in understanding this pattern.


publish/subscribe is a similiar pattern: a publisher is like an observable, a subscriber like an observer. And another practical example: one can subscribe to a newspaper and the publisher will send the paper until you cancel your subscription.


The bag.addObserver() can be made only because IntegerDataBag extends Observable?

Correct, Observable is a class that has the addObserver() method.

Where is this observer being add to? what being created and where?

The Observer class contains a List or Vector (in the JDK source) of Observable objects.

private Vector obs;

That's where it's stored.

What is the different between setChanged() and notifyObservers()?

The setChanged() just marks the Observable is changed. The notifyObservers() just calls the all observers it has on the list to update() (passing a changed object to the Observer) only if the setChanged is set to true.

I don't understand the update method- what does args stands for? and why do I need to check that o==bag, why would I update another observable?

The update() method tells the Observer that it needs to update based on the changed obj it receives. This is called by the notifyObservers() from Observable.

Why should I need this observer anyway?

To create a Listener for event driven scenario, i.e. if you want to be informed in the change of your observable objects, then Observer is needed.

Read: GoF - Observer pattern.


The bag.addObserver() can be made only because IntegerDataBag extends Observable?

Yes.

2.Where is this observer being add to? what being created and where?

Into the related Observable class, which your class is extending.

4.I don't understand the update method- what does args stands for?

It's called when the state of an observed object has changed. The args is the parameter passed to nofityObserver.

and why do I need to check that o==bag, why would I update another observable?

You don't need to check anything.

5.Why should I need this observer anyway?

It's a very useful design pattern. Have a look to wikipedia article.

EDIT: I missed point :

What is the different between setChanged() and notifyObservers()?

setChanged() marks an object signalling that it changed. notifyObservers is responsible to wake all observer listening to the observable object.


The bag.addObserver() can be made only because IntegerDataBag extends Observable?

Yes, the addObserver method is implemented in Observable.

Where is this observer being add to? what being created and where?

The observer is being added to a list of observers which is declared in Observable as private, so it is not visible in your subclass.

What is the different between setChanged() and notifyObservers()?

When you call notifyObservers() without first calling setChanged(), no notifications take place.

I don't understand the update method- what does args stands for? and why do I need to check that o==bag, why would I update another observable?

One Observer can watch multiple Observables. By examining the first parameter of the update method, you can figure out which observer is notifying you about something.

Why should I need this observer anyway?

Any time you want a class to send events to other classes but you don't want a direct dependency from that class on its observers.


In answer to your points.

  1. Yes you're correct

  2. The observer is added to a list maintained in the Observable object

  3. You need to call setChanged() before you notify observers, otherwise they won't know the object has changed. Once you call notifyObservers(), All obvserers are notified of the change. If you don't call setChanged first, your observers won't be notified.

  4. arg is anything you'd like to pass to Observers when you call notifyObservers(arg);


The observer pattern is similar to the concept of listeners. The object which is being listened to maintains a record of all of it's listeners. For instance, a stock monitor class may allow objects to listen for a certain event, such as the stock level falling below the warning level.

From the observer's point of view:

Call subscribe() or addEventListener()or the like. The observer is then "notified" when the event actually occurs, usually by means of calling a function in the observer (the event handler function).

from the observable's point of view:

Objects wishing to observe the observable object register their interest by calling the subscribe() or addEventListener() as above. The observable thus adds these observers to an array, list, or some other data structure.

Once the event actually happens, the listeners are notified by calling the event handler function in the observers' class.


The update() method is called by the Observable. This method is called by calling notifyObservers(), which itterates trough all Observers and calls update on them. This informs the Observer that the object they are watching has been changed and a certain action can be performed. The args object is whatever you want it to be, it can be null aswell but it can be used to inform the observers what type of update just took place.


The bag.addObserver() can be made only because IntegerDataBag extends Observable?

Yes, that's the whole point.

Where is this observer being add to? what is being created and where?

It adds IntegerAdder to the list of classes that observe IntegerDatabag for changes. From now on, if a change occurs on IntegerDataBag, it will notify IntegerAdder via the notifyObservers() method, which will trigger its update() method.

What is the difference between setChanged() and notifyObservers()?

notifyObservers() calls the update() method of every observer of your observable, and is used to pass infos to this method. As for setChanged(), it marks your object as "changed" so that the hasChanged() method will now return true... It's used to monitor changes to your observable class.

I don't understand the update method- what does args stands for?

The update() method is inherited from the implementation of the observer interface - You have to implement it. The Object arg is an optional argument that you can pass to the method via notifyObservers().

Why do I need to check that o==bag, why would I update another observable?

Since an observer can "observe" more than one "observable", you need to check that it's really IntegerDatabag that triggered update(), hence o==bag.

Why should I need this observer anyway?

You need the observer to monitor IntegerDataBag for changes. In your case, you print a message in the console when IntegerDatabag is modified. The purpose of the Observer/Observable model is specifically to monitor changes on specific objects, and then update the program based on the changes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜