What is the difference between the observer mode in the eyes of masters

Posted Jun 6, 202022 min read

Observer mode is a mode that uses a lot of things. It is the first time to understand. It is just to write an example based on the introductory demo, but I don t know where and how to use it. It is a textbook.
Personally, I like blogs or materials that are more practical.
I made a hungry one more recently, I feel a little bit of a harvest, record it.

Basic part

  1. The basic classic structure of the observer pattern

Insert picture description here
Insert picture description here

Second, the entry small demo

Classic small demo1:

Insert picture description here
Observer

/**
 * Observer interface, define an updated interface for those who are notified when the target changes
 */
public interface Observer {
    /**
     * Updated interface
     */
    public void update(Subject subject);
}

ConcreteObserver

//Specific observer object, implement the update method, use its own state and
public class ConcreteObserver implements Observer {

    @Override
    public void update(Subject subject) {
        //Specific implementation
        //Here it may be necessary to update the state of the observer to keep it consistent with the state of the target
        String message =((ConcreteSubject) subject).getSubjectState();
        System.out.println("Received a notification:The status obtained is:"+ message);
    }

}

Subject

/**
 * Target object, it knows the observer who observes it, and provides an interface to register and delete observers
 */
public class Subject {
    /**
     * Used to save registered observer objects
     */
    private List<Observer> observers = new ArrayList<>();
    /**
     * Registered observer object
     */
    public void attach(Observer observer){
        observers.add(observer);
    }
    /**
     * Delete observer object
     */
    public void detach(Observer observer){
        observers.remove(observer);
    }
    /**
     * Notify all registered observer objects
     */
    protected void notifyObservers(){
        for(Observer observer:observers){
            observer.update(this);
        }
    }

}

ConcreteSubject

/**
 * The specific target object, responsible for saving the relevant state to the corresponding observer object
 * And in your own state
 */
public class ConcreteSubject extends Subject {
    /**
     * Status of target audience
     */
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();
    }
}

Test

public class Test {
    public static void main(String[]args) {
        //Observer
        Observer concreteObserver1 = new ConcreteObserver();
        Observer concreteObserver2 = new ConcreteObserver();
        //The target object is the observed object. There can be multiple targets. This demo is distinguished by state
        ConcreteSubject subject1 = new ConcreteSubject();
        //Register observer
        subject1.attach(concreteObserver1);
        subject1.attach(concreteObserver2);
//ConcreteSubject subject2 = new ConcreteSubject();
////Register observer
//subject2.attach(concreteObserver1);
//subject2.attach(concreteObserver2);
        //make a notification
        subject1.setSubjectState("Notice 1:Has been issued");
//System.out.println("===change theme======");
//subject2.setSubjectState("Notice 2:Has been issued");

    }
}

Running result:The subject sends a message, and the observer can receive:
Insert picture description here

A small case of janitor and whistle in the design mode

Insert picture description here
Subject

public interface Subject {

    /**
     * Add observer
     * @param observer
     */
    void addObserver(Observer observer);
    /**
     * Remove the specified observer
     * @param observer
     */
    void removeObserver(Observer observer);
    /**
     * Remove all observers
     */
    void removeAll();

    /**
     * data is the data to be notified to the observer
     * Because Object is the parent class of all classes, you can use polymorphism, of course, you can also use generics
     * @param data
     */
    void notifyAllObserver(Object data);

    /**
     * Individually notify a certain observer
     * @param observer
     * @param data
     * data is the data to be notified to the observer
     * Because Object is the parent class of all classes, you can use polymorphism, of course, you can also use generics
     */
    void notify(Observer observer,Object data);

}

ConcreteSubject

/**
 * Specific subject objects
 * Thread safety is not implemented here,
 * If you are interested, you can refer to Observable under java.util
 * @author xujun
 *
 */

public class ConcreteSubject implements Subject {

    List<Observer> mList = new ArrayList<>();

    @Override
    public void addObserver(Observer observer) {
        //Make sure that the same observer contains only one
        if(observer == null) {
            throw new NullPointerException("observer == null");
        }
        if(!mList.contains(observer)) {
            mList.add(observer);
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        mList.remove(observer);
    }

    @Override
    public void removeAll() {
       mList.clear();
    }

    @Override
    public void notifyAllObserver(Object data) {
        for(Observer observer:mList) {
            observer.update(data);
        }
    }

    @Override
    public void notify(Observer observer, Object data) {
        if(observer!=null){
            observer.update(data);
        }
    }

}

Observer

/**
 * Observer interface
 * @author Administrator
 *
 */
public interface Observer {

    /**
     *
     * @param data The data passed by the observer to the observer
     */
    void update(Object data);


}

CartoonObserver

public class CartoonObserver implements Observer {

    @Override
    public void update(Object data) {
        System.out.println("I am"+this.getClass().
                getSimpleName()+", "+data+"Don t read comics");
    }

}

NBAObserver

public class NBAObserver implements Observer {
    public class CartoonObserver implements Observer {

        @Override
        public void update(Object data) {
            System.out.println("I am "+this.getClass().getSimpleName()+", "+data+"don't read comics");
        }
    }

    @Override
    public void update(Object data) {
        System.out.println(" I am" + this.getClass().getSimpleName() + ", "+ data + "Don't watch the NBA anymore");
    }

}

TestObserver

public class TestObserver {

    public static void main(String[]args) {
        //theme
        ConcreteSubject concreteSubject = new ConcreteSubject();
        //Observer
        CartoonObserver cartoonObserver = new CartoonObserver();
        NBAObserver nbaObserver = new NBAObserver();
        //Add observer
        concreteSubject.addObserver(cartoonObserver);
        concreteSubject.addObserver(nbaObserver);
       //Post news notification
        concreteSubject.notifyAllObserver("Teacher is here");
    }
}

Operation result:As long as the notice sent out, the observer received it.
Insert picture description here

  1. Two ways to use the classic observer mode:push and pull

When using the observer mode, there are actually two stages:

  • Preparation stage, the stage of maintaining the relationship between the target and the observer
  • The actual operation stage, that is, the stage where the goal changes, causing the observer to make a response

The usage method mentioned here refers to the actual operation stage. The problem of getting the exact data originator of the target.

  • Push the model

The target object actively pushes the detailed information of the target to the observer, whether or not the observer needs it, these data are the definition of the target object, which is equivalent to broadcasting to the observer. In the previous example, the second one is the push model.

  • Pull model

When the target object notifies the observer, it just gives its own reference to the observer, and the observer uses the reference to obtain it as needed. In the previous example, the first example is the pull model. The target object this is passed to the observer.

If the data is determined during development, you can use the push model. If the data to be obtained by the observer is not fixed, it is recommended to use the pull model, which is more flexible and scalable. In short, it is better to pull the model.


`Novices generally only learn above. Let's enter into the part of deep thinking:


Advanced part(application scenario)

  1. How to make observers treat differently

The above demos are all notified when the observer is notified at present. According to different situations, let different observers handle the operation. How to design?

Thoughts:2 types,
One is that the target can be fully notified, but the observer does not do anything,
The other is to make judgments in the target without notification.
The second option is recommended here, which can unify logical control and perform unified dispatch of observers, which is conducive to business control and future expansion.

Here is an example:Water quality pollution, according to the pollution situation, notify the inspectors, early warning personnel, and inspection department leaders.
The generation is as follows:
Insert picture description here

WaterQualitySubject-the target of water quality monitoring

/**
 * Define the target audience for water quality monitoring
 */
public abstract class WaterQualitySubject {
    /**
     * Used to save registration
     */
    protected List<WatcherObserver> observers = new ArrayList<>();
    /**
     * Registered observer object
     */
    public void attach(WatcherObserver observer){
        observers.add(observer);
    }
    /**
     * Delete observer object
     */
    public void detach(WatcherObserver observer){
        observers.remove(observer);
    }
    /**
     * Notify the corresponding observer object
     */
    public abstract void notifyWathers();
    /**
     * Get the level of water pollution
     */
    public abstract int getPolluteLevel();

}

WaterQuality-specific water quality monitoring objects

/**
 * Specific water quality monitoring objects
 */
public class WaterQuality extends WaterQualitySubject {
    /**
     * Pollution level, 0 means normal, 1 means light pollution, 2 means moderate pollution, 3 means high pollution
     */
    private int polluteLevel = 0;

    /**
     * Get the level of water pollution
     */
    @Override
    public int getPolluteLevel() {
        return polluteLevel;
    }

    public void setPolluteLevel(int polluteLevel) {
        this.polluteLevel = polluteLevel;
        this.notifyWathers();
    }

    /**
     * Notify the corresponding observer object
     */
    @Override
    public void notifyWathers() {
        //The observer registered in the loop
        for(WatcherObserver watcher:observers){
            //Start to judge whether notification is needed according to pollution level
            if(this.polluteLevel >=0){
                //Notify the monitor to make records
                if((""monitor").equals(watcher.getJob())){
                    watcher.update(this);
                }
            }
            if(this.polluteLevel >=1){
                //Notify the early warning personnel
                if(("Warning personnel").equals(watcher.getJob())){
                    watcher.update(this);
                }
            }
            if(this.polluteLevel >=2){
                //Notify the monitor department leader
                if(("Monitoring Department Leader").equals(watcher.getJob())){
                    watcher.update(this);
                }
            }

        }
    }

}

WatcherObserver

public interface WatcherObserver {
    /**
     * How to be notified
     * @param subject
     */
    public void update(WaterQualitySubject subject);
    /**
     * Set the position of the observer
     */
    public void setJob(String job);
    /**
     * Obtain the position of the observer
     */
    public String getJob();


}

Watcher

public class Watcher implements WatcherObserver{
    private String job;

    @Override
    public void update(WaterQualitySubject subject) {
        //Here is the pull method
        System.out.println(job+"Obtained notification, current pollution level is:" + subject.getPolluteLevel());
    }

    @Override
    public void setJob(String job) {
        this.job = job;
    }

    @Override
    public String getJob() {
        return this.job;
    }
}

Test

public class Test {
    public static void main(String[]args) {
        //Create water quality theme object
        WaterQuality subject = new WaterQuality();
        //Create several observers
        WatcherObserver watcher1 = new Watcher();
        watcher1.setJob("Monitor");
        WatcherObserver watcher2 = new Watcher();
        watcher2.setJob("Warning personnel");
        WatcherObserver watcher3 = new Watcher();
        watcher3.setJob("Monitoring Department Leader");
        //Register observer
        subject.attach(watcher1);
        subject.attach(watcher2);
        subject.attach(watcher3);
        //Fill in the water quality report
        System.out.println("When the water quality is normal------------");
        subject.setPolluteLevel(0);
        System.out.println("When the water quality is light pollution-------------");
        subject.setPolluteLevel(1);
        System.out.println("When the water quality is moderate pollution-------------");
        subject.setPolluteLevel(2);
    }
}

operation result:
Insert picture description here

It can be seen that different observers are notified according to the warning level.
The main logic is on the target object implementation class, which is a more clever way of judging if, not if. . else if... but multiple if. Combine if, learn and learn from it, and use it for reference later.

Second, how to implement the observer pattern without relying on abstract observers:

The above examples all have the role of an abstract observer, and the target object directly operates the abstract observer. If you do not want to use abstract observers, consider the following ideas:

    1. We create a new abstract observer class, others provide it, we just implement it, here we can use the observer pattern that comes with java, he has helped us automatically provide an abstract observer, and an abstract target class, We just use it according to his rules.

      • []Here will be an example of using the observer mode that comes with java:
    1. The work of registering the observer and notifying the observer is handed over to a third party to decouple the target from the observer.

There are many ways to achieve this, the main idea is reflection delegation.

Four examples will be shown here:

  • []Reflect the commission to implement the second example above. In class, look at nba and anime. The teacher came and made different examples of different reactions.
  • []For example:an example that imitates the realization principle of the swing component(This example is very special, the observer can observe multiple target objects)
  • []Example of listener implementation of observer mode in spring
  • []springboot uses eventBus provided by Guava framework to implement event processing examples.

1. Example of using the observer pattern that comes with java

Java provides abstract observer Observer, abstract target object Observable, and the method name to inform the observer must be update. Before notification, the setChange() method must be called, the specific code is as follows:

Specific target class(observed)

/**
 * Title:GPer
 * Description:An implementation of observer provided by JDK
 *
 * @author hfl
 * @version V1.0
 * @date 2020-06-03
 */
public class GPer extends Observable {
    private String name = "GPer Ecosystem";
    private static GPer gper = null;

    private GPer() {
    }

    public static GPer getInstance(){
        if(null == gper){
            gper = new GPer();
        }
        return gper;
    }

    public void publishQuestion(Question question){
        System.out.println(question.getUserName() + "A question was submitted on "+ this.name + ".");
        setChanged();
        notifyObservers(question);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Here is an auxiliary class, a business class that has nothing to do with the observer pattern:Question

/**
 * Title:Question
 * Description:TODO
 *
 * @author hfl
 * @version V1.0
 * @date 2020-06-03
 */
public class Question {
    //questioner
    private String userName;
    //Ask a question
    private String content;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Specific observer class:Teacher

public class Teacher implements Observer {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        GPer gper =(GPer)o;
        Question question =(Question)arg;
        System.out.println("==============================="=";
        System.out.println(name + "Teacher, hello!\n" +
                "You have received a question from "" + gper.getName() + "". I hope you will answer it. The content of the question is as follows:\n" +
                question.getContent() + "\n" +
                "Questioner:" + question.getUserName());
    }
}

Test class:

public class ObserverTest {
    public static void main(String[]args) {
        GPer gper = GPer.getInstance();
        Teacher tom = new Teacher("Tom");
        Teacher mic = new Teacher("Mic");

        //This is no @Tom  
        Question question = new Question();
        question.setUserName("  ");
        question.setContent("Which scenarios does the observer design pattern apply to?");
        gper.addObserver(tom);
        gper.addObserver(mic);
        gper.publishQuestion(question);
    }
}

operation result:
Insert picture description here
Viewing the results perfectly shows the realization that the target object notifies all observers.

2. Reflect delegation to implement the second example above, an example where students respond differently according to the arrival of the teacher.

Specific code:
Insert picture description here

/**
 * Event object encapsulation class
 *
 * @author Administrator
 */
public class Event {
    //Object to execute method
    private Object object;
    //The name of the method to be executed
    private String methodName;
    //The parameters of the method to be executed
    private Object[]params;
    //The parameter type of the method to be executed
    private Class[]paramTypes;

    public Event() {

    }

    public Event(Object object, String methodName, Object... args) {
        this.object = object;
        this.methodName = methodName;
        this.params = args;
        contractParamTypes(this.params);
    }

    //Generate parameter type array according to parameter array
    private void contractParamTypes(Object[]params) {
        this.paramTypes = new Class[params.length];
        for(int i = 0; i <params.length; i++) {
            this.paramTypes[i]= params[i].getClass();
        }
    }


    public Object getObject() {
        return object;
    }

    //Some omitted get and set methods

    /**
     * According to the method name and method parameters of the object, use the reflection mechanism to execute the method
     *
     * @throws Exception
     */
    public void invoke() throws Exception {
        Method method = object.getClass().getMethod(this.getMethodName(), this.getParamTypes());
        if(null == method) {
            return;
        }
        method.invoke(this.getObject(), this.getParams());
    }


    public void setObject(Object object) {
        this.object = object;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public Object[]getParams() {
        return params;
    }

    public void setParams(Object[]params) {
        this.params = params;
    }

    public Class[]getParamTypes() {
        return paramTypes;
    }

    public void setParamTypes(Class[]paramTypes) {
        this.paramTypes = paramTypes;
    }
}

EventHandler

/**
 * Title:EventHandler
 * Description:The handler of the event
 *
 * @author hfl
 * @version V1.0
 * @date 2020-06-05
 */
public class EventHandler {
    //Use a List
    private List<Event> objects;

    public EventHandler(){
        objects=new ArrayList<Event>();
    }
    //Add the event to be executed by an object and the required parameters
    public void addEvent(Object object,String methodName,Object...args){
        objects.add(new Event(object,methodName,args));
    }
    //Notify all objects to execute the specified event
    public void notifyX() throws Exception{
        for(Event e:objects){
            e.invoke();
        }
    }
}

Notifier's abstract class Notifier

public abstract class Notifier {
    private EventHandler eventHandler = new EventHandler();

    public EventHandler getEventHandler() {
        return eventHandler;
    }

    public void setEventHandler(EventHandler eventHandler) {
        this.eventHandler = eventHandler;
    }

    /**
     * Add students who need help to whistle
     *
     * @param object The object to execute the method
     * @param methodName The method name of the execution method
     * @param args The parameters of the execution method
     */
    public abstract void addListener(Object object, String methodName, Object... args);

    /**
     * Tell all the students who want to help the whistle:the teacher is here
     */
    public abstract void notifyX();
}

Notifier GoodNotifier

public class GoodNotifier extends Notifier {

    @Override
    public void addListener(Object object, String methodName, Object... args) {
        System.out.println("A new classmate entrusts a whistleblower with due diligence!");
        EventHandler handler = this.getEventHandler();
        handler.addEvent(object, methodName, args);
    }

    @Override
    public void notifyX() {
        System.out.println("The whistleblower tells all the students who need help:the teacher is here");
        try{
            this.getEventHandler().notifyX();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

WatchCartoonListener

/**
 * Title:WatchCartoonListener
 * Description:Specific listener(observer)
 *
 * @author hfl
 * @version V1.0
 * @date 2020-06-05
 */
public class WatchCartoonListener extends GoodNotifier {

    public WatchCartoonListener() {
        System.out.println("WatchCartoonListener I am watching cartoons, start time:"+ LocalDateTime.now().toString());
    }

    public void stopPlayingGame(Date date){
        System.out.println("WatchCartoonListener stopped watching cartoons, end time:"+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(date));
    }
}

WatchingNBAListener

public class WatchingNBAListener extends GoodNotifier {
    public WatchingNBAListener() {
        System.out.println("WatchingNBAListenerI am watching the NBA, the start time is:"+ LocalDateTime.now().toString());
    }
    public void stopWatchingTV(Date date){
        System.out.println("WatchingNBAListener close NBA live broadcast, the end time is:"+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(date));
    }
}

Test class:

public class Test {
    public static void main(String[]args) {
        //Create a responsible whistleblower
        Notifier goodNotifier = new GoodNotifier();

//Create a classmate who plays the game and start playing the game
        WatchCartoonListener playingGameListener = new WatchCartoonListener();

//Create a classmate watching TV and start watching TV
        WatchingNBAListener watchingTVListener = new WatchingNBAListener();
//The classmate who played the game told the sentinel classmate, the teacher came to tell
        goodNotifier.addListener(playingGameListener, "stopPlayingGame", new Date());
//The student watching TV told the sentinel, the teacher came to tell
        goodNotifier.addListener(watchingTVListener, "stopWatchingTV", new Date());
        try {
            //After a while
            Thread.sleep(1000);
        } catch(Exception e) {
            e.printStackTrace();
        }
//The teacher appears, the sentinel informs all the students who need help:the teacher is here
        goodNotifier.notifyX();


    }
}

operation result:

public class Test {
    public static void main(String[]args) {
        //Create a responsible whistleblower
        Notifier goodNotifier = new GoodNotifier();

//Create a classmate who plays the game and start playing the game
        WatchCartoonListener playingGameListener = new WatchCartoonListener();

//Create a classmate watching TV and start watching TV
        WatchingNBAListener watchingTVListener = new WatchingNBAListener();
//The classmate who played the game told the sentinel classmate, the teacher came to tell
        goodNotifier.addListener(playingGameListener, "stopPlayingGame", new Date());
//The student watching TV told the sentinel, the teacher came to tell
        goodNotifier.addListener(watchingTVListener, "stopWatchingTV", new Date());
        try {
            //After a while
            Thread.sleep(1000);
        } catch(Exception e) {
            e.printStackTrace();
        }
//The teacher appears, the sentinel informs all the students who need help:the teacher is here
        goodNotifier.notifyX();


    }
}

operation result:
Insert picture description here

Event delegation mechanism analysis

  1. The whistleblower is completely unaware of the existence of the game player and completely decoupled.(Of course, credit goes to Event and EventHandler, and these two classes are universal)
  2. When the teacher comes, the player stops the game and returns to the seat, the NBA player stops watching the NBA, the manga stops watching the manga, and the game stops playing the game.(One notification, different methods of different classes are executed)
  3. The scalability is very high, and then another basketball student will first write a basketball student class, and tell the whistle-blower in the test code. The whistle-blower has not changed at all. Good reusability

After reading this example, it is much simpler to understand the example of the monitoring of the swing component, because the principle is exactly the same, and there are events and event handlers to manage and call observer methods.

3.Swing component monitoring example

Specifically look at the code:

Insert picture description here

This example is more powerful. It not only exemplifies the registration of the observer, but also the method of a certain observer corresponds to the specific method of a certain target class, and the method to method correspondence. Understand well, learn, and strive to use in the project:
Event

public class Event {
    //Event source, who initiated the event and saved it
    private Object source;
    //The event is triggered, who to notify
    private Object target;
    //Event triggered, what action to do, callback
    private Method callback;
    //The name of the event, what event is triggered
    private String trigger;
    //Time when the event was triggered
    private long time;

    public Event(Object target, Method callback) {
        this.target = target;
        this.callback = callback;
    }

    public Event setSource(Object source) {
        this.source = source;
        return this;
    }

    public Event setTime(long time) {
        this.time = time;
        return this;
    }
    public Event setTrigger(String trigger) {
        this.trigger = trigger;
        return this;
    }
    public Object getSource() {
        return source;
    }


    public long getTime() {
        return time;
    }

    public Object getTarget() {
        return target;
    }

    public Method getCallback() {
        return callback;
    }

    @Override
    public String toString() {
        return "Event{" + "\n" +
                "\tsource=" + source.getClass() + ",\n" +
                "\ttarget=" + target.getClass() + ",\n" +
                "\tcallback=" + callback + ",\n" +
                "\ttrigger='" + trigger + "',\n" +
                "\ttime=" + time + "'\n" +
                '}';
    }
}

EventLisenter

public class EventLisenter {
    //Lisenter at the bottom of JDK is usually designed like this
    protected Map<String, Event> events = new HashMap<String, Event>();

    //Event name and a target object to trigger the event
    public void addLisenter(String eventType, Object target) {
        try {
            this.addLisenter(
                    eventType,
                    target,
                    target.getClass().getMethod("on" + toUpperFirstCase(eventType), Event.class));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void addLisenter(String eventType, Object target, Method callback) {
        //Registration issue
        events.put(eventType, new Event(target, callback));
    }


    //Trigger, trigger whenever there is action
    private void trigger(Event event) {
        event.setSource(this);
        event.setTime(System.currentTimeMillis());

        try {
            //Initiate callback
            if(event.getCallback() != null) {
                //Call its callback function with reflection
                event.getCallback().invoke(event.getTarget(), event);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //Event name trigger
    protected void trigger(String trigger) {
        if(!this.events.containsKey(trigger)) {
            return;
        }
        trigger(this.events.get(trigger).setTrigger(trigger));
    }

    //Private method for logical processing, capitalized
    private String toUpperFirstCase(String str) {
        char[]chars = str.toCharArray();
        chars[0]-= 32;
        return String.valueOf(chars);
    }

}

Mouse

public class Mouse extends EventLisenter {

    public void click(){
        System.out.println("Call Click Method");
        this.trigger(MouseEventType.ON_CLICK);
    }

    public void doubleClick(){
        System.out.println("Call the double-click method");
        this.trigger(MouseEventType.ON_DOUBLE_CLICK);
    }

    public void up(){
        System.out.println("Call the pop-up method");
        this.trigger(MouseEventType.ON_UP);
    }

    public void down(){
        System.out.println("Call the press method");
        this.trigger(MouseEventType.ON_DOWN);
    }

    public void move(){
        System.out.println("Call mobile method");
        this.trigger(MouseEventType.ON_MOVE);
    }

    public void wheel(){
        System.out.println("Call scroll method");
        this.trigger(MouseEventType.ON_WHEEL);
    }

    public void over(){
        System.out.println("Call hover method");
        this.trigger(MouseEventType.ON_OVER);
    }

    public void blur(){
        System.out.println("Call the focus method");
        this.trigger(MouseEventType.ON_BLUR);
    }

    public void focus(){
        System.out.println("Call out-of-focus method");
        this.trigger(MouseEventType.ON_FOCUS);
    }
}

MouseEventCallback

/**
 * Logic written by yourself for callback
 * Created by Tom.
 */
public class MouseEventCallback {

    public void onClick(Event e){
        System.out.println("=========== Trigger mouse click event ==========" + "\n" + e);
    }

    public void onDoubleClick(Event e){
        System.out.println("=========== Trigger mouse double-click event ==========" + "\n" + e);
    }

    public void onUp(Event e){
        System.out.println("=========== Trigger mouse up event ==========" + "\n" + e);
    }

    public void onDown(Event e){
        System.out.println("=========== Trigger mouse down event ==========" + "\n" + e);
    }

    public void onMove(Event e){
        System.out.println("=========== Trigger mouse movement event ==========" + "\n" + e);
    }

    public void onWheel(Event e){
        System.out.println("=========== Trigger mouse scroll event ==========" + "\n" + e);
    }

    public void onOver(Event e){
        System.out.println("=========== Trigger mouseover event ==========" + "\n" + e);
    }

    public void onBlur(Event e){
        System.out.println("=========== Trigger mouse out of focus event ==========" + "\n" + e);
    }

    public void onFocus(Event e){
        System.out.println("=========== Trigger mouse focus event ==========" + "\n" + e);
    }

}

MouseEventType

public interface MouseEventType {
    //Click
    String ON_CLICK = "click";

    //Double click
    String ON_DOUBLE_CLICK = "doubleClick";

    //Bouncing
    String ON_UP = "up";

    //Press
    String ON_DOWN = "down";

    //mobile
    String ON_MOVE = "move";

    //scroll
    String ON_WHEEL = "wheel";

    //Hover
    String ON_OVER = "over";

    //Out of Focus
    String ON_BLUR = "blur";

    //Focused
    String ON_FOCUS = "focus";
}

MouseEventTest

public class MouseEventTest {
    public static void main(String[]args) {

        MouseEventCallback callback = new MouseEventCallback();

        Mouse mouse = new Mouse();

        //@Who? @Callback method
        mouse.addLisenter(MouseEventType.ON_CLICK,callback);
        mouse.addLisenter(MouseEventType.ON_FOCUS,callback);

        mouse.click();

        mouse.focus();


    }
}

public class Keybord extends EventLisenter {

    public void down(){

    }

    public void up(){

    }

}

operation result:
Insert picture description here

4. Example of listener implementation in spring

Spring's event mechanism uses the observer pattern. In this mode, a target object manages all observer objects that depend on it, and actively sends notifications when its own state changes. This is usually achieved by calling the method provided by each observer. This mode is usually used to implement event processing systems.
In Spring, each listener is equivalent to an observer. The event event is equivalent to the target, the observer, and the container is used to manage and register the observer, and publish the event.

The specific demo code is as follows:
Insert picture description here

Event class:OrderEvent is equivalent to the target class

public class OrderEvent extends ApplicationEvent {

    public OrderEvent(Object source) {
        super(source);
    }
}

OrderSmsListener is equivalent to an observer

@Component
public class OrderSmsListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent orderEvent) {
        System.out.println("orderSmsListener receive event from "+ orderEvent.getSource());
    }
}

Business:

@Service
public class OrderService {

    @Autowired
    private ApplicationContext applicationContext;


    public void order() {
        applicationContext.publishEvent(new OrderEvent("orderService"));
    }
}

In addition, the spring container is equivalent to the delegate class.
test:

@RunWith(SpringRunner.class)
@SpringBootTest
public class PatternApplicationTest {

    @Autowired
    private OrderService orderService;

    @Test
    public void contextLoads() {
    }


    @Test
    public void testOrder() {
        orderService.order();
    }

}

operation result:
Insert picture description here
It is shown that after the event is released, you can observe this event by listening to it, and you can do more operations.

4. Integrate Google's Guava in springboot, realize subscription and release function through eventBus

EventBus does not need to implement complex events, listeners, and publishers. What I said earlier is class-oriented. Now:Guava is method-oriented and more powerful. A solution to easily observe the pattern on the floor.

An example:
Introducing Guava's package:

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>

EventBus EventBus

//api package
public class MyEventBus {

    /** Event task bus */
    private final static EventBus tiemEventBus = new EventBus();
    /**
     * Trigger synchronization event
     *
     * @param event
     */
    public static void post(Object event) {
        tiemEventBus.post(event);
    }
    /**
     * Register event handler
     *
     * @param handler
     */
    public static void register(Object handler) {
        tiemEventBus.register(handler);
    }
    /**
     * Log off event handler
     *
     * @param handler
     */
    public static void unregister(Object handler) {
        tiemEventBus.unregister(handler);
    }
}

Message entity class

public class Message {
    private MessageType messageType;
    private String messageContent;

    public Message(MessageType messageType, String messageContent) {
        this.messageType = messageType;
        this.messageContent = messageContent;
    }
    public MessageType getMessageType() {
        return messageType;
    }
    public void setMessageType(MessageType messageType) {
        this.messageType = messageType;
    }
    public String getMessageContent() {
        return messageContent;
    }
    public void setMessageContent(String messageContent) {
        this.messageContent = messageContent;
    }

    public enum MessageType {
        OPENDOOR(1, "openDoor"),
        CLOSEDOOR(2,"closeDoor");
        private int code;
        private String value;

        MessageType(int code, String value) {
            this.code = code;
            this.value = value;
        }
        public int getCode() {
            return code;
        }
        public void setCode(int code) {
            this.code = code;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        }
}

Event listener

@Component
abstract class MyApplicationListener implements ApplicationListener<ApplicationPreparedEvent> {
    /**
     * ApplicationPreparedEvent context preparation event
     * @param applicationPreparedEvent
     */
    @Override
    public void onApplicationEvent(ApplicationPreparedEvent applicationPreparedEvent) {
        ConfigurableApplicationContext applicationContext = applicationPreparedEvent.getApplicationContext();
        MyApplicationListener bean = applicationContext.getBean(this.getClass());
        System.out.println("regist listener to eventBus...."+bean);
        MyEventBus.register(bean);
    }
}


         MyApplicationListener 

@Component
public class MyListentenerSubscribe extends MyApplicationListener{
    @Subscribe
    public void on(Message message){
        System.out.println("subscribe message->  messgeType "+message.getMessageType()+"\n messageContent "+message.getMessageContent());
    }
}

:

@RestController
public class EventPublishCtrl extends LogBase {
    @GetMapping("/publish")
    public void publishEvent() {
        log.info("this publish method...");
        MyEventBus.post(new Message(Message.MessageType.OPENDOOR,"     "));
    }
}


        :




                   demo    2              java              ;                       swing         spring listener           springboot  eventBus         .              

                    mq                

:
https://blog.csdn.net/gdutxia...
https://blog.csdn.net/fw19940...
https://www.cnblogs.com/wkzha...


  de     
                 !


Finish