An analysis of the observer model
Simply put, the Observer pattern defines a one-to-many dependency that allows one or more observer objects to monitor a subject object. Changes in the state of such a Subject object can inform all those observer objects that depend on the object so that the observer objects can be automatically updated.
Structure of the Observer pattern
The Observer (Observer) pattern is an object's behavioral pattern, also known as the Publish-subscribe (publish/subscribe) mode, model-view (model/view) mode, source-listener (source/ Listener) mode or dependent (dependents) mode.
The class diagram structure of this pattern is as follows:
Figure 1, the static structure of the observer pattern can be seen clearly from the class diagram. |
The following roles are available in the Observer mode:
. Abstract Theme (Subject) role : A theme role keeps references to all the Observer objects in a list, and each topic can have any number of observers. A theme provides an interface to add or revoke an observer object, and the subject role is also called the Abstract Observer (observable) role;
Figure 2, the abstract theme role, sometimes called the abstract observer role, can be implemented with an abstract class or an interface, and the use of a specific class implementation is not excluded in specific cases. |
. abstract Observer (Observer) role : Defines an interface for all specific observers, updating themselves when notified;
Figure 3, the abstract observer role, can be implemented with an abstract class or an interface, and not excluded from the use of specific class implementations in specific cases. |
. The specific theme (concretesubject) role : To preserve the internal state that is useful to a specific observer object, to send a notification to its observer when such internal state changes; The specific theme role is called the specific observer role;
Figure 4, specific theme roles, usually implemented with a specific subclass. |
. specific observer (concreteobserver) role : holds a reference to a specific subject object, and a state consistent with the state of the subject. The specific observer role implements the update of its own interface as required by the abstract observer role so that its state and theme are in their own state.
Figure 5, the specific observer role, usually implemented with a specific subclass. |
Here is a schematic implementation of the Java code. First, in this schematic implementation, the abstract theme role is implemented with a Java interface, which is the following subject interface:
public interface Subject { public void Attach (Observer Observer);
public void Detach (Observer Observer);
void Notifyobservers (); } |
Code Listing 1, the source code for the subject interface.
This abstract topic interface sets out the operations that three subclasses must implement, that is, attach () is used to add an observer object, detach () to delete an observer object, and Notifyobservers () to notify each observer to refresh themselves. Abstract theme roles actually require subclasses to keep a list of all the observer objects as elements.
The specific theme is the implementation of the abstract theme subject interface of a specific class, it gives the above three operations of the concrete implementation. As can be seen from the source code below, the Java implementation given here uses a Java vector to hold all the observer objects, while the Attach () and detach () operations are additions and deletions to the vector's elements.
Import Java.util.Vector; Import java.util.Enumeration;
public class ConcreteSubject implements Subject { public void Attach (Observer Observer) { Observersvector.addelement (Observer); }
public void Detach (Observer Observer) { Observersvector.removeelement (Observer); }
public void Notifyobservers () { Enumeration enumeration = observers (); while (Enumeration.hasmoreelements ()) { ((Observer) enumeration.nextelement ()). Update (); } }
Public enumeration observers () { Return ((Vector) Observersvector.clone ()). elements (); } Private Vector Observersvector = new Java.util.Vector (); } |
Code Listing 2, the source code for the ConcreteSubject class.
The implementation of the abstract observer role is actually the simplest one, a Java interface that declares only one method, update (). This method after the Quilt class implementation, a call will refresh itself.
public interface Observer { void Update (); } |
Code Listing 3, the source code for the Observer interface.
The implementation of the specific observer role only involves the implementation of the update () method. How this method is implemented is closely related to application, so this class only gives a framework.
public class Concreteobserver implements Observer { public void Update () { Write Your code here } } |
Code Listing 4, the source code for the Concreteobserver class.
Although the implementation of the observer pattern can be determined by the designer itself, the observer pattern is important in the Java language because the event model of the Windows system starts with the observer pattern from AWT1.1. For this reason, the Java language gives its own support for the Observer pattern. Therefore, this article recommends that readers use the support provided by the Java language when applying observer mode to their systems.
Support for the observer pattern provided by the Java language
In the Java.util Library of the Java language, a observable class and a observer interface are provided to form the Java language's support for the Observer pattern.
Observer interface
This interface defines only one method, update (). This method is invoked when the state of the observed object changes. The implementation of this method should call the Notifyobservers () method of each object being observed, thus notifying all the observed objects.
Figure 6, the class diagram of the Observer interface provided by Java.util. |
Package java.util;
public interface Observer { /** * This method is invoked when the object being observed is changed. */ void update (Observable o, Object Arg); } |
Code Listing 5, the source code for the Java.util.Observer interface.
Observable class
The observed class are subclasses of the Java.util.Observable class. Java.util.Observable provides a public way to support the Observer object, which has two important subclasses of observable: one is setchanged () and the other is Notifyobservers (). After the first method setchanged () is invoked, an internal tag variable is set, representing a change in the state of the object being observed. The second is notifyobservers (), which, when invoked, invokes the update () method of all registered observer objects so that the observer objects can update themselves.
There are other important ways to java.util.Observable the class. For example, an observer object can invoke the Addobserver () method of the Java.util.Observable class to add an object one to a list. When there is a change, this list can tell the Notifyobservers () method that the Observer object needs to be notified. Because the list is private, Java.util.Observable's child objects do not know that the Observer object has been observing them.
Figure 7, the class diagram of the observed person provided by the Java language. |
The source code of the Observer class observable:
Package java.util; public class observable { Private Boolean changed = FALSE; Private Vector Obs;
The/** constructs a observed by 0 observers. **/
Public observable () { OBS = new Vector (); }
/** * Add an observer to the list of observers. */ Public synchronized void Addobserver (Observer o) { if (!obs.contains (o)) { Obs.addelement (o); } }
/** * Remove an Observer object from the list of observers. */ Public synchronized void Deleteobserver (Observer o) { Obs.removeelement (o); }
/** * Equivalent to notifyobservers (NULL) */ public void Notifyobservers () { Notifyobservers (NULL); }
/** * If this object has a change (then the Haschanged method returns True) * Call this method to notify all registered observers that the update () method is invoked, * Incoming this and arg as parameters. */ public void Notifyobservers (Object arg) { /** * Temporarily store the status of the current observer. See Memo mode. */ Object[] arrlocal;
Synchronized (This)
|