Observer Mode
The Observer model is designed to meet the need for listening. That is, when something happens, one or more observers need to be aware of the event, and if each observer uses polling to determine whether the event occurs, it consumes more resources. So the task should be done by the observed, that is, the observer holds multiple observer objects, and notifies all observers when an event occurs to them. Such a mechanism is the observer model.
But there are some security issues, such as when the Observer holds the observer, and the observer is completely exposed to the observer, which should be avoided. So it is natural to draw the concept of an interface to unify the behavior of the observer, the observer only holds the interface, and any object that implements the interface can be held as an observer and other details of the object are not open to the observer.
The observer pattern has been encapsulated in Java, and we can emulate it to implement our own observer pattern.
First, as we mentioned earlier, the observer should provide a unified interface for the observer to invoke, namely:
Observer
Public interface Observer {
void update (observable observable, object);
}
For the observer, it is more complex, and we can find a few major steps:
Serial Number |
Steps |
1 |
Hold the Observer |
2 |
Judge whether there is a change |
3 |
INFORM the Observer |
So we can write the abstract class of the observed:
Public abstract class Observable {
private list<observer>observers = new arraylist<> ();
Private Boolean ischanged;
public void Addobserver (Observer Observer) {
observers.add (Observer);
}
public void setchanged () {
ischanged = true;
}
public void Notifyobservers (Object object) {
if (ischanged) {
Observers.foreach (Observer-> Observer.update (this, object));
ischanged = false;}}}
So we define the interface of the observer and the abstract class of the observer.
In fact, in the implementation of the JDK, observable will have perfect thread security, such as the list of the host observer is implemented in vector, and vector itself is thread-safe, such as observable The methods in are added with the synchronize identifier to notify the observer in a thread-safe manner. But that's not the point here, so it's no longer detailed.
Let's look at a practical application:
In our case, there is a student and a number of teachers, students ask questions, these questions will be submitted to the teacher (notify the observer), the teacher will judge whether they can do, give students feedback.
Here we have two teachers, one is a math teacher, an art teacher, the current setting is that they each answer only one question, encountered the rest of the problem will be skipped.
Take a look at the specific code:
Tea_math
public class Tea_math implements observer{
private String name = "Math teacher:";
@Override public
void Update (observable observable, object) {
String question = (string) Object;
What is the meaning of question.equals ("Matrix multiplication")? ")" {
System.out.println (name + "is a coordinate transformation in some way");
} else {
System.out.println (name + "I'm not quite sure, you ask the other teacher");}
Tea_art
public class Tea_art implements observer{
private String name = "Art teacher:";
@Override public
void Update (observable observable, object) {
String question = (string) Object;
if (question.equals) ("Monet's Water lily" is the work of his later years?) {
System.out.println (name + "is a series of works in his later years");
} else {
System.out.println (name + "I'm not quite sure, you ask the other teacher");}
Stu
public class Stu extends observable{public
void Ask (String question) {
System.out.println ("Question:" + question);
Setchanged ();
Notifyobservers (question);
}
Actual Call:
public class Client {public
static void Main (string[] args) {
Stu Stu = new Stu ();
Tea_math Tea_math = new Tea_math ();
Tea_art Tea_art = new Tea_art ();
Stu.addobserver (Tea_math);
Stu.addobserver (Tea_art);
Stu.ask ("What is the meaning of matrix multiplication?") ");
Stu.ask ("The Water lily of Monet" was his work in his later years.) ");
}
}
We can look at the results of the operation:
Question: What is the meaning of matrix multiplication?
Math teacher: In a way, it's a transformation of coordinates.
Art Teacher: I don't know, you ask other teachers
Question: Is the water lily of Monet the work of his later years?
Math Teacher: I don't know, you ask other teachers.
Art Teacher: A series of works in his later years
The above is the description of the observer pattern and the implementation of the code, should be more clear. Callback:
Callbacks are designed to meet the needs of the caller. If the caller needs to perform an action, and it has to define itself what to do after the action is completed. This time the action is emitted by the caller itself, but the completion of the action needs to be implemented by the caller, so how does the caller know what to do next after the action is completed? How does it know how to follow the caller's definition? A callback is needed at this time, and the basic steps to implement a callback are:
Serial Number |
Steps |
1 |
The caller defines an action |
2 |
The callee that executes the action is then specified (holding the callee) |
3 |
Define subsequent actions to be performed after the action is completed |
4 |
Finally, this follow-up action is communicated to the caller (or, optionally, to the callee). Typically, the callee is a system application, that is, we inform the system of the application of our subsequent actions and let them perform our operations after they are completed. |
You can drill down with the implementation of the Click event:
If there is a textview as the caller, a onclicklistener as the callee
TextView should hold Onclicklistener, so it has a Setonclicklistener method
And it has to perform the onclick action, so it has the click Method.
And for the caller Onclicklistener,
It is the actual finish of the click Action, so it has the OnClick method.
In this way, you can write the structure of both:
TextView
public class TextView {
//hold the callee
private Onclicklistener onclicklistener;
public void Setonclicklistener (Onclicklistener onclicklistener) {
this.onclicklistener = Onclicklistener;
}
public void Click () {
Onclicklistener.onclick ("TextView", 1);
}
Onclicklistener
Public interface Onclicklistener {
void OnClick (String view, int position);
}
Actual call to client:
public class Client_click {public
static void Main (string[] args) {
TextView TextView = new TextView ();
Internal class, specifying the callee
//At this point, Onclicklistener can be viewed as a system application, and we will inform the system application of our own subsequent actions, and let it call
Textview.setonclicklistener (new Onclicklistener () {
@Override public
void OnClick (String view, int position) {
Define subsequent actions
System.out.println (view);
System.out.println (position);
}
);
Textview.click ();
}
The code above is clear enough to understand the meaning of the callback.
The
links and distinctions between callback and observer patterns, as well as their applicable environment, can be judged in combination with actual circumstances. I'm going to have time to write about it in a few days.