Research on JDK Observer Design Mode

xiaoxiao2021-03-06  200

The current design model is more and more articles, but the research model of the design model is still lacking, which is a bit regrettable. This article aims to throw brick jade, specifically analyze the OBServer design mode of JDK in Java (not particularly pointed out below, the OBServer design mode means the implementation of the OBServer design mode of JDK in Java).

1. Observer design pattern summary

Observer design mode belongs to behavioral design mode in GOF. The implementation of the OBServer design pattern provided in JDK consists of Java.util.observable class and Java.util.observer interface. From the name, you can clearly see the roles that both play in OBSERVER design mode: OBServer is the observer role, OBSERVABLE is a Subject role.

Observable is a class package Subject's basic feature, such as registering Observer, logout Observer (Detatch function). These functions are any classes that play the Observerable role. From this point, JDK is specially packaged in a class, which is reasonable. Normally, our class can be called Observerable role class as long as it is derived from the OBSerVerable class, and it is very simple to use.

2. Difficulties with the use of Observer design patterns

But we have to pay attention to the actual development of the project, often more complicated. Java does not support multi-inheritance characteristics Many times are hindering stumbling blocks we use Observer design patterns. For example, a class we designed is already a class of derived classes. In this case, it will make it troublesome to play Observerable roles. How to achieve "more inheritance" is a big problem in front of us. Below we first analyze the OBSERVABLE class.

3. Principle of Observable class "trigger notification"

Observable must "change" to trigger the OBServer this task, which is an essential embody. You can know the source code. Observerable part of the source code is as follows:

// ... 省 省 ...

PRIVATE BOOLEAN CHANGED = FALSE;

// ... 省 省 ...

Public void NotifyObservers (Object Arg) {

// ... 省 省 ...

Object [] arrlocal;

Synchronized (this) {

// ... 省 省 ...

IF (! Changed)

Return;

Arlocal = obs.toArray ();

ClearChanged ();

}

// ... 省 省 ...

protected synchronized void setchanged () {

Changed = true;

}

Protected synchronized void clearchanged () {

Changed = false;

}

As shown in the thick plasma label section, in the NotifyObservers (Object Arg) method, if the statement tells us that if the CHANGED attribute value is false, it will return directly, and the notification operation is not triggered. And we note that the change attribute is initialized to false, which will mean if we don't actively set the change attribute to true, will not have any changes, that is, the "notification" role is not found. Therefore, the value of setting the change attribute is the key to our application JDK Observer design mode. So how can you set the change attribute? As can be seen from the source code, the only entry is through SetChanged (). Below we analyze the change attributes and related methods setChanged () and ClearChanged (). 4. Analysis of OBSERVABLE class

Observable # Changd Attribute is false, which is easy to understand, no longer detailed. Careful readers may notice two methods related to the Changed property setChanged () and ClearChanged (), and their modifiers are protected. It is important to emphasize that it is protected instead of public. But does this have its necessity and rationality? The answer is yes. In the previous analysis, I have already mentioned that the setChanged () method is to set the unique portal of Changed, which is defined as protected, which means that the change attribute will become impossible by defining the OBSERVABLE object. In this sense, if you want to apply the OBServer design mode, you must inherit the OBSERVABLE class. About this, will mention below. However, why can't I define into public? This seems to be difficult to understand. Whatever we can easily set the value of the ChangeD property? In order to figure out this problem, let's take a look at the related code in Observable:

// ... 省 省 ...

Public void NotifyObservers (Object Arg) {

// ... 省 省 ...

For (int I = arrlocal.length-1; i> = 0; I -)

(OBServer) arrlocal [i]). Update (this, arg);

}

The expression of this code is to say that all registered Observer is found, and the "Notification" will be conducted one by one, and the notification is made by calling the OBServer # Update (Object) method. We see that Update's first parameter is this, we must also notice that this code is the code in the OBSERVABLE class. This is equivalent to repeatedly emphasizing, "Notifications" must be OBSERVABLE (OBSERVABLE or the class), and any other classes are not. This means that our OBServable class inherits the OBSERVABLE class is necessary, because if not inherited, while using a combination, it will not be guaranteed to pass the THIS. In other words, use the OBSERVABLE class in a combination, it will become almost no meaning. At the same time, the modifier is defined as protected, ensuring that trigger notifications in Obsrvable will not be notified anywhere, which seems to be strong. If the setChanged () modifier is defined as public, it will not guarantee the hard requirements of correct "transfer this", which does not comply with the "OBSERVALBE can directly or indirectly notify Observer" this ObserVable design mode hard requirement. From this, we can see how strong the ideological ideas of JDK is. 5. Solve difficulties in using Observer design model

With the Adapter design mode (see the Adapter design mode related articles published by those) and Java support multi-interface feature can basically solve the "multi-inheritance" problem. Basic thinking is to achieve effects in combination inheritance / implementation and combinations. In the above analysis, we already know that the OBSERVABLE class must inherit the use and cannot be used, so we only need to play a class that needs to be played into an OBSERVERABLE role, and the original inherited class is dressed as an adaptee role. . The sample code is as follows:

// To act as the original code of the class of the OBSERVABLE role:

Public class myObject extends baseObject {

Public myObject () {

Public void method1 () {}

}

}

/ / Act as the code after the OBSERVABLE role:

Public class myObject extends observable {

Private baseObject baseObject = null;

Public MyObject (BaseObject BaseObject) {

THIS.BASEOBJECT = BASEOBJECT;

}

}

6. Precautions:

If the baseObject in the above example also uses the method that needs to pass "this", then the above combination method will be possible to fail. This situation is the worst case. At this point, you can consider that the BaseObject class "bottleneck" is allowed to use an interface instead of class (including abstract classes).

About author

Originally famous Gu Naizhong, is now a senior technical personnel of Guangzhou IT, graduated from University in 2001. Focus on Java and C related technology learning and research. You can contact Gunzh (Beyondsoul) via gunzh@126.com.

转载请注明原文地址:https://www.9cbs.com/read-128230.html

New Post(0)