Asynchronous notification and event callback based on Guava API

This article is excerpted from "design patterns should be learned this way"

1 implementation of notification mechanism based on Java API

When small partners ask questions in the community, if there is a setting to specify the user to answer, the corresponding user will receive an email notification, which is an application scenario of observer mode. Some small partners may think of MQ and asynchronous queues. In fact, JDK itself provides such API s. We use code to restore such an application scenario. First, create the GPer class.

/**
 * JDK Provides an implementation of the observer, the observed
 */
public class GPer extends Observable{
    private String name = "GPer Ecosphere";
    private static GPer gper = null;
    private GPer(){}

    public static GPer getInstance(){
        if(null == gper){
            gper = new GPer();
        }
        return gper;
    }
    public String getName() {
        return name;
    }
    public void publishQuestion(Question question){
        System.out.println(question.getUserName() + "stay" + this.name + "A question was submitted on.");
        setChanged();
        notifyObservers(question);
    }
}

Then create the Question class.

public class Question {
    private String userName;
    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;
    }
}

Then create the Teacher class.

public class Teacher implements Observer {

    private String name;

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

    public void update(Observable o, Object arg) {
        GPer gper = (GPer)o;
        Question question = (Question)arg;
        System.out.println("======================");
        System.out.println(name + "Hello, teacher!\n" + 
"You received a message from" + gper.getName() + "I hope you can answer my question. The questions are as follows:\n" +
                   question.getContent() + "\n" + "Questioner:" + question.getUserName());
    }
}

Finally, write the client test code.

    public static void main(String[] args) {
        GPer gper = GPer.getInstance();
        Teacher tom = new Teacher("Tom");
        Teacher jerry = new Teacher("Jerry");

        gper.addObserver(tom);
        gper.addObserver(jerry);

        //User behavior
        Question question = new Question();
        question.setUserName("Zhang San");
        question.setContent("What scenes does observer mode apply to?");

        gper.publishQuestion(question);
}

The operation results are shown in the figure below.

2. Easy landing observer mode based on Guava API

The author recommends a very easy-to-use framework for implementing the observer mode, and the API is also very simple. For example, first introduce the Maven dependency package.

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

Then create the listening event GuavaEvent.

/**
 * Created by Tom
 */
public class GuavaEvent {
    @Subscribe
    public void subscribe(String str){
        //Business logic
        System.out.println("implement subscribe method,The parameter passed in is:" + str);
    }

}

Finally, write the client test code.


/**
 * Created by Tom
 */
public class GuavaEventTest {
    public static void main(String[] args) {
        EventBus eventbus = new EventBus();
        GuavaEvent guavaEvent = new GuavaEvent();
        eventbus.register(guavaEvent);
        eventbus.post("Tom");
    }

}

3 use observer mode to design mouse event response API

Then design a business scenario to help the partners better understand the observer model. In the JDK source code, there are many applications of observer mode. For example, java.awt.Event is a kind of observer mode, but Java is rarely used to write desktop programs. We use code to realize it, so as to help our friends have a deeper understanding of the implementation principle of observer mode. First, create the EventListener interface.

/**
 * Observer abstraction
 * Created by Tom.
 */
public interface EventListener {

}

Create an Event class.


/**
 * Definition of standard event source format
 * Created by Tom.
 */
public class Event {
    //Event source, who sent the action
    private Object source;
    //Who (observer) should be notified when the event is triggered
    private EventListener target;
    //Observer response
    private Method callback;
    //Name of the event
    private String trigger;
    //Trigger event of event
    private long time;

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

    public Object getSource() {
        return source;
    }

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

    public String getTrigger() {
        return trigger;
    }

    public Event setTrigger(String trigger) {
        this.trigger = trigger;
        return this;
    }

    public long getTime() {
        return time;
    }

    public Event setTime(long time) {
        this.time = time;
        return this;
    }

    public Method getCallback() {
        return callback;
    }

    public EventListener getTarget() {
        return target;
    }

    @Override
    public String toString() {
        return "Event{" +
                "source=" + source +
                ", target=" + target +
                ", callback=" + callback +
                ", trigger='" + trigger + '\'' +
                ", time=" + time +
                '}';
    }
}

Create an EventContext class.

/**
 * The abstraction of the observed
 * Created by Tom.
 */
public abstract class EventContext {
    protected Map<String,Event> events = new HashMap<String,Event>();

    public void addListener(String eventType, EventListener target, Method callback){
        events.put(eventType,new Event(target,callback));
    }

    public void addListener(String eventType, EventListener target){
        try {
            this.addListener(eventType, target, 
target.getClass().getMethod("on"+toUpperFirstCase(eventType), Event.class));
        }catch (NoSuchMethodException e){
            return;
        }
    }

    private String toUpperFirstCase(String eventType) {
        char [] chars = eventType.toCharArray();
        chars[0] -= 32;
        return String.valueOf(chars);
    }

    private void trigger(Event event){
        event.setSource(this);
        event.setTime(System.currentTimeMillis());

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

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

Then create the MouseEventType interface.

/**
 * Created by Tom.
 */
public interface MouseEventType {
    //single click
    String ON_CLICK = "click";

    //double-click
    String ON_DOUBLE_CLICK = "doubleClick";

    //Bounce
    String ON_UP = "up";

    //Press
    String ON_DOWN = "down";

    //move
    String ON_MOVE = "move";

    //roll
    String ON_WHEEL = "wheel";

    //hover
    String ON_OVER = "over";

    //Lose focus
    String ON_BLUR = "blur";

    //Get focus
    String ON_FOCUS = "focus";
}

Create the Mouse class.

/**
 * Specific observer
 * Created by Tom.
 */
public class Mouse extends EventContext {

    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 bounce 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 move 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 get focus method");
        this.trigger(MouseEventType.ON_BLUR);
    }

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

Create a callback method mouseeventlistener class.

/**
 * Observer
 * Created by Tom.
 */
public class MouseEventListener implements EventListener {


    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 pop-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 mouse over 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 the mouse to get focus event==========" + "\n" + e);
    }

}

Finally, write the client test code.

    public static void main(String[] args) {
        EventListener listener = new MouseEventListener();

        Mouse mouse = new Mouse();
        mouse.addListener(MouseEventType.ON_CLICK,listener);
        mouse.addListener(MouseEventType.ON_MOVE,listener);

        mouse.click();
        mouse.move();
    }
        

Focus on WeChat's official account of Tom architecture and reply to the "design pattern" to get the complete source code.

[recommendation] Tom bomb architecture: 30 real cases of design patterns (with source code attached). Challenging the annual salary of 60W is not a dream

This article is the original of "Tom bomb architecture". Please indicate the source for reprint. Technology lies in sharing, I share my happiness!
If this article is helpful to you, you are welcome to pay attention and praise; If you have any suggestions, you can also leave comments or private letters. Your support is the driving force for me to adhere to my creation. Focus on WeChat official account Tom structure, get more dry cargo!

Tags: Java Design Pattern architecture

Posted on Wed, 17 Nov 2021 03:06:39 -0500 by dmort