Home>

The observer pattern defines a one-to-many dependency,Have multiple observer objects listen to a topic object at the same time.

When this theme object changes state,Will notify all observers,Let them update themselves automatically.

I. Introduction to the Observer Mode

Observer pattern is implemented in observable class and observer interface in java.An observer object watches for changes in an observable object,When the observable object changes,observer is notified,Then you can work accordingly.

If screen a shows the data in the database,Screen b modifies the data in the database.Then at this time picture a will be reloaded. At this time, you can use the observer mode

Second, the observer mode implementation method

There are two methods in java.util.observable that are especially important for observers

①setchanged () method

/**
* sets the changed flag for this {@code observable}. after calling
* {@code setchanged ()}, {@code haschanged ()} will return {@code true}.
* /
protected void setchanged () {
changed=true;
}
② notifyobservers () method/notifyobservers (object data) method
[java] view plaincopy
/**
* if {@code haschanged ()} returns {@code true}, calls the {@code update ()}
* method for every observer in the list of observers using null as the
* argument. afterwards, calls {@code clearchanged ()}.
*<p>
* equivalent to calling {@code notifyobservers (null)}.
* /
public void notifyobservers () {
notifyobservers (null);
}
/**
* if {@code haschanged ()} returns {@code true}, calls the {@code update ()}
* method for every observer in the list of observers using the specified
* argument. afterwards calls {@code clearchanged ()}.
*
* @param data
* the argument passed to {@code update ()}.
* /
@suppresswarnings ("unchecked")
public void notifyobservers (object data) {
int size=0;
observer [] arrays=null;
synchronized (this) {
if (haschanged ()) {
clearchanged ();
size=observers.size ();
arrays=new observer [size];
observers.toarray (arrays);
}
}
if (arrays!=null) {
for (observer observer:arrays) {
observer.update (this, data);
}
}
}

The above two methods are very important

setchanged () method-

Used to set an internal flag to indicate that data has changed

notifyobservers () method/notifyobservers (object data) method-

Notify all observers that the data has changed,At this time, all observers will automatically call the replicated update (observable observable, object data) method to do some processing (such as updating the screen data).

We can see that there are two ways to notify the observer,One without parameters,One has ginseng.So what does this parameter do?

One of the functions:Now I don't want to notify all observers, but only want one of the specified observers to do some processing,Then you can pass a parameter as the id, and then judge it in all observers. Each observer judges that it only does the processing if it receives the parameter id in the end.

Of course, parameters have other functions,I just gave an example.

Here is an example:

import java.util.observable;
/**
* Observed class
* /
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;
setchanged ();
//Only after setchange () is called,notifyobservers () will call update (), otherwise nothing will be done.
notifyobservers ();
}
}
}

The above class is an observed class,It inherits the observable class, indicating that this class is observable.

Then in the setdata () method,Where the data changes,To call the setchanged () method and notifyobservers () method of the observable class to indicate that the data has changed and notify all observers to call their update () method to do some processing.

Note:Only after setchange () is called,notifyobservers () will call update (), otherwise nothing will be done.

/**
* Observer
* /
public class simpleobserver implements observer
{
public simpleobserver (simpleobservable simpleobservable) {
simpleobservable.addobserver (this);
}
public void update (observable observable, object data) {//data is an arbitrary object,Used to pass parameters
system.out.println ("data has changed to" + (simpleobservable) observable.getdata ());
}
}

By generating an instance of the observed person (simpleobservable class), the addobserver (this) method is called to allow the observer (simpleobserver class) to observe the observed object (simpleobservable class).

Then you need to override the update () method to do some processing after the data changes.

Let's write a simple test class to test it

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);
}
}

The results are as follows

data has changed to 1

data has changed to 2 //The update is not called because there is no setchange in the second setdata (2)

data has changed to 3

Here are some other properties and methods of an observable class

Attributes --

//observers is a list that holds all observers to be notified.

list<observer>observers=new arraylist<observer>();

//changed is a boolean flag,Marks whether the data has changed.

boolean changed=false;

Method ——

//add an observer to the list observers
public void addobserver (observer observer) {
if (observer == null) {
throw new nullpointerexception ();
}
synchronized (this) {
if (! observers.contains (observer))
observers.add (observer);
}
}
//remove an observer from the list of observers
public synchronized void deleteobserver (observer observer) {
observers.remove (observer);
}
//empty list observers
public synchronized void deleteobservers () {
observers.clear ();
}
//return the number of observers in the list observers
public int countobservers () {
return observers.size ();
}
//reset the data change flag to unchanged
protected void clearchanged () {
changed=false;
}
//Set the data change flag to change
protected void setchanged () {
changed=true;
}
//determine the value of the flag
public boolean haschanged () {
return changed;
}
//notify all observers (no parameters)
public void notifyobservers () {
notifyobservers (null);
}
//notify all observers (with parameters)
@suppresswarnings ("unchecked")
public void notifyobservers (object data) {
int size=0;
observer [] arrays=null;
synchronized (this) {
if (haschanged ()) {
clearchanged ();
size=observers.size ();
arrays=new observer [size];
observers.toarray (arrays);
}
}
if (arrays!=null) {
for (observer observer:arrays) {
observer.update (this, data);
}
}
}

Note:Before observer objects are destroyed, they must be deleted from the list with deleteobserver.That is, the deleteobserver () method is called in the ondestroy () method.

Otherwise, because there is still a relationship of object references,observer objects are not garbage collected,Causing memory leaks,And the dead observer will still be notified,May cause unexpected errors,And as the list grows,The notifyobservers operation will also become slower and slower.

of The roles involved in the observer mode are:

● abstract subject role:The abstract subject role stores all references to observer objects in an aggregate (such as an arraylist object), and each topic can have any number of observers.The abstract theme provides an interface,You can add and delete observer objects,Abstract theme roles are also called abstract observable roles.

● concretesubject role:store related states into specific observer objects;When the internal state of a specific topic changes,Give notice to all registered observers.Specific theme roles are also called concrete observable roles.

● abstract observer role:define an interface for all concrete observers,Update yourself when notified about a topic,This interface is called the update interface.

● Concrete observer role:Stores the state that matches the state of the subject.The concrete observer role implements the update interface required by the abstract observer role,In order to reconcile the state of the subject with the state of the subject. If needed,A specific observer role can maintain a reference to a specific topic object.

  • Previous Difference between serializeArray () and serialize () in jQuery
  • Next JavaScript programming JS debugging