Definition: Define a one-to-many dependency between objects, so that when each object changes its state, all objects that depend on it will be notified and automatically updated.
Type: Behavioral Pattern
Class diagram:
There is often a need in software systems: if the state of an object changes, some objects related to it will also change accordingly. For example, we want to design a right-click menu function. As long as we right-click in the effective area of the software, a menu will pop up; for example, we want to design an automatic deployment function, just like when eclipse is developed, as long as the file is modified, eclipse will automatically deploy the modified file to the server. There is a similarity between these two functions, that is, one object must always monitor another object, and as long as its state changes, it will take corresponding actions. In fact, there are many solutions that can achieve this, but using the observer model is undoubtedly a mainstream choice.
The structure of the observer pattern
In the most basic observer mode, the following four characters are included:
Observer: From the class diagram, you can see that there is a Vector container in the class that stores the observer object (the reason why Vector is used instead of List is because when multi-threaded operations, Vector is safe, while List is unsafe). This Vector container is the core of the observer class. There are three other methods: the attach method is to add the observer object to this container; the detach method is to remove the observer object from the container; the notify method is to call the corresponding methods of the observer object in turn. This role can be an interface, an abstract class or a concrete class, because in many cases it will be mixed with other patterns, so there are more cases of using abstract classes.
Observer: The observer role is generally an interface, which has only one update method. When the state of the observer changes, this method will be called.
Specific observer: This role is used for easy expansion, and specific business logic can be defined in this role.
Specific Observer: The specific implementation of the observer interface. In this role, the logic to be processed when the state of the object being observed changes.
Observer mode implementation example
Subject interface
public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyAllObservers();}Observer interface
public interface Observer { public void update(Subject s);}The Hunter class implements the Subject interface
import java.util.ArrayList; public class HeadHunter implements Subject{ //define a list of users, such as Mike, Bill, etc. private ArrayList<Observer> userList; private ArrayList<String> jobs; public HeadHunter(){ userList = new ArrayList<Observer>(); jobs = new ArrayList<String>(); } @Override public void registerObserver(Observer o) { userList.add(o); } @Override public void removeObserver(Observer o) {} @Override public void notifyAllObservers() { for(Observer o: userList){ o.update(this); } } public void addJob(String job) { this.jobs.add(job); notifyAllObservers(); } public ArrayList<String> getJobs() { return jobs; } public String toString(){ return jobs.toString(); }}JobSeeker is an observer:
public class JobSeeker implements Observer { private String name; public JobSeeker(String name){ this.name = name; } @Override public void update(Subject s) { System.out.println(this.name + " got notified!"); //print job list System.out.println(s); }}Get started:
public class Main { public static void main(String[] args) { HeadHunter hh = new HeadHunter(); hh.registerObserver(new JobSeeker("Mike")); hh.registerObserver(new JobSeeker("Chris")); hh.registerObserver(new JobSeeker("Jeff")); //Every time you add a job, all jobs can be notified. hh.addJob("Google Job"); hh.addJob("Yahoo Job"); }} Advantages of Observer Mode
The observer and the observer are slightly related and are abstractly coupled, so that it is easier to expand for both.
The observer mode is a commonly used trigger mechanism, which forms a trigger chain and processes the methods of each observer in turn. But at the same time, this is also a disadvantage of the observer mode. Since it is triggered in a chain, when there are many observers, the performance problem is more worrying. Moreover, in the chain structure, circular reference errors are more likely to occur, causing the system to be faked.
Summarize
In the Java language, there is an interface Observer, and its implementation class Observable, which often implements the observer role. We can view the usage methods of these two classes in the JDK API documentation.
Friends who have done VC++, javascript DOM or AWT development are all amazing about their event processing. After understanding the observer pattern, they have a certain understanding of the principles of the event processing mechanism. If you want to design a function of an event triggering processing mechanism, using the observer mode is a good choice. The event processing DEM (Delegation Event Model) in AWT is implemented using the observer mode.