In this section, we will introduce a relatively simple but powerful mode: The Observer mode. I hope that after reading this article, we can have a comprehensive and perceptual understanding of the design model.
In many cases, experience is crucial for a design (software, building, or industrial. Good experiences give us guidance and save our time. Bad experiences give us reference to reduce the risk of failure. However, in terms of knowledge, experience only exists in the personal brain as a kind of accumulation of work and is difficult to be transferred or recorded. To solve this problem, people have proposed the so-called model concept. The so-called Mode refers to the repeated problem solutions under a specific background. The mode is experience-based documentation.
The concept of software pattern is now widely used, involving analysis, design, architecture, coding, testing, refactoring, and other parts of the software construction life cycle. Here we mainly discuss the design pattern, which refers to the solutions to some repeated problems in the software design process. However, when we mention the design pattern, it generally refers to the 23 patterns in the Design Pattern -- elements of reusable object-oriented software, a classic gof book. Therefore, it is specific to the object-oriented software design process.
Globally, the pattern represents a language, a documented experience, or even a culture. There are often many problems that are difficult to describe or are complicated to describe. Speaking in a pattern language will make the listener feel enlightened. Of course, both parties must be able to grasp the meaning of the Model language. However, this is not an easy task. Patterns are often different in understanding. This article aims to explain the design patterns from a specific application perspective: Java class libraries. Combined with specific examples, we hope to deepen our understanding of the design model.
The Java class library mentioned here is not limited to JDK itself, but also some examples of other class libraries, such as JAXP (of course, the next JDK version will also contain JAXP ). In fact, the concept of design patterns is now so widely used. No matter what kind of design, as long as a slightly larger design, many traces of design patterns can be found, or it is inevitable to use the design pattern. Most of the design patterns described below are the 23 patterns that have appeared in the gof classic. However, some, such as MVC, do not belong to them. Generally speaking, we think that the 23 gof models are intermediate ones, and some lower-layer models can be abstracted below them, you can also combine them to obtain some advanced modes. Of course, the differences between low, medium, and high levels are similar to the differences between different languages. They are only differences at the application layer.
Observer Mode
The function of the observer mode is to expect two or more objects, called subject and observer. When the status of one party changes, the other party will be notified. That is to say, as the observer side, it can monitor a specific state change of the subject and respond to it. A simple example is: when the data in a user view is changed by the user, the backend database can be updated, and when the database is updated in other ways, the data display in the user view also changes.
Figure 1: class diagram of the obverser Mode
In JDK, there is actually a simple implementation of the observer mode: Class java. util. observerable and interface java. util. Observer. The Java. util. observerable class corresponds to subject, while Java. util. Observer is the observer. In JDK, these two parts are not designed as interfaces. Instead, java. util. observerable provides partial implementation, which simplifies many programming tasks. Of course, this also reduces some flexibility.
The following lists the functions of observer and observeral and their simple functions.
java.util.Observer:
public void update(Observable obs, Object obj)
Java. util. the observer interface is very simple. Only this method is defined. In a narrow sense, according to the observer mode, observer should call the getxxx () method of subject in this method to obtain the latest status, in fact, you can only respond to certain subject events. This is a prototype of the proxy event model in Java-responding to events. However, in the Observer mode, the event is specified as a State/data change.
Java. util. observable
Public void addobserver (Observer obs)
Register an observer with subject. That is to say, add the observer object to the internal list of Java. util. observable. In JDK, this list is simply implemented through a java. util. vector class, but in fact, in some complicated observer mode applications, we need to place this part separately to form a manager class to manage mappings between subject and observer. In this way, the subject and observer are further decoupled, and the program will be more flexible.
Public void deleteobserver (Observer obs)
Delete a reference with registered observer from subject.
Public void deleteobservers ()
Delete all registered observer references from subjec.
Public int countobservers ()
Returns the number of observers registered in subject.
Protected void setchanged ()
Set an internal flag to indicate that the ovserver status has changed. Note that this is a protected method, that is, it can only be called in the Observer class and its subclass, but not in other classes.
Protected void clearchanged ()
Clear the internal identifier of the file. It is automatically called within the yyobservers () method to indicate that the status change of the subject has been passed to the ovserver.
Public Boolean haschanged ()
Determine whether the status of the subject has changed.
Public void policyobservers (Object OBJ)
It first checks the internal flag to determine whether the status has changed. If yes, it calls the update () method of each observer registered in the subject. In JDK, this method is implemented internally as synchronized, that is, if multiple threads compete for a java. util. if the observerable policyobservers () method is used, they must be executed in the order of scheduling. In some special circumstances, there may be some potential problems: during the waiting process, a newly added observer will be missed and not notified, A deleted observer still receives a notification that it does not want.
Public void policyobservers ()
It is equivalent to calling policyobservers (null ).
Therefore, it is easy to apply the observer in Java. It is necessary to make the subject object to be observed inherit Java. util. observerable, let the object to be observed implement Java. util. observer interface, and then use Java. util. the observerable addobserver (Observer OBJ) method registers the observer to the subject object. This has completed most of the work. Then, the observer mode mechanism can be implemented by calling methods such as notifyobservers (Object Arg) of Java. util. observerable. Let's take a simple example of using this mode. In this example, there are three classes: framesubject, datesubject, frameobject, and entryclass. In framesubject, users can set the observed values, which are automatically displayed in frameobject, datesubject encapsulates the observed value and acts as the subject in the Observer mode.
Public class framesubject extends jframe {.............. // Because multi-inheritance cannot be used, you can only use object combination to introduce a // java. util. observerable object. Datesubject subject = new datesubject (); // This method forwards the added observer message to datesubject. Public void registerobserver (Java. util. Observer O) {subject. addobserver (o) ;}// data change. After the event is triggered, notifyobservers () is called to notify Observer. Void jbutton?action=med (actionevent e) {subject. setwidthinfo (integer. parseint (jtextfield1.gettext (); Subject. setheightinfo (integer. parseint (jtextfield2.gettext (); Subject. yyobservers ();}...............} Public class datesubject extends observable {// encapsulate the observed data private int widthinfo; private int heightinfo; Public int getwidthinfo () {return widthinfo;} public void setwidthinfo (INT widthinfo) {This. widthinfo = widthinfo; // after the data changes, setchanged () must be called, otherwise the yyobservers () method does not work this. setchanged ();} public void setheightinfo (INT heightinfo) {This. heightinfo = heightinfo; this. setchanged ();} public int Ge Theightinfo () {return heightinfo;} public class frameobserver extends jframe implements java. util. Observer {.............. // The observed data int widthinfo = 0; int heightinfo = 0; // The update () method updates the data and other necessary responses. Public void Update (observable o, object Arg) {datesubject subject = (datesubject) O; widthinfo = subject. getwidthinfo (); heightinfo = subject. getheightinfo (); jlabel1.settext ("The heightinfo from subject is:"); jlabel3.settext (string. valueof (heightinfo); jlabel2.settext ("The widthinfo from subject is:"); jlabel4.settext (string. valueof (widthinfo ));}................} Public class entryclass {public static void main (string [] ARGs ){................. Framesubject frame = new framesubject (); frameobserver frame2 = new frameobserver (); // register the observer in the subject and associate the two into a frame. registerobserver (frame2 );.............. Frame. setvisible (true); frame2.setvisible (true );................. }} |
I think the implementation of this observer mode in JDK is very sufficient for general observer mode applications. However, on the one hand, it uses a class to implement subject, and on the other hand, it uses vector to save subject references to observer, which simplifies the programming process, but it will limit its application in some scenarios that require more flexibility and complex design. Sometimes (although this is not the case ), we have to rewrite the new subject object and additional manager object to implement more complex observer mode applications.