Detailed explanation of observer mode of internal mental skill of architect, publish first and then subscribe

Keywords: Spring JDK Google

Application scenarios of observer mode

The dynamic notification of wechat friend circle in life, the email notification in work, the broadcast notification on the school playground, the event response of the computer desktop application and so on are all real life scenes of the observer mode. Observer Pattern defines a one to many dependency between objects. It allows multiple observers to listen to a principal object. When the principal object changes, all its observers will be notified and updated. Watcher mode is also called publish subscribe mode.

1.1 cases of students' online questions

Now, during the new coronavirus epidemic, many students encounter problems in their study at home, so it is inevitable to ask their own teachers. When students ask questions on an education platform, if there is a designated Teacher to answer, the corresponding teacher will be notified by the corresponding email, which is an application scenario of observer mode. When we get this need, we may think of some technical means such as asynchronous queue and message middleware MQ. In fact, JDK itself provides such an API. Then we will write the example code about this scenario and 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;
    }
}

The Education class of the observed of the re created Education platform inherits the Observable:

public class Education extends Observable {

    private final String EDU_NAME = "xxx Internet Education Platform";

    private Education() {}

    private static Education education = null;

    public static Education getInstance() {
        if(null == education) {
            education = new Education();
        }
        return education;
    }

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

}

Create a Teacher class to implement the Observer interface:

public class Teacher implements Observer {

    private String name;

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

    @Override
    public void update(Observable o, Object arg) {
        Education education = (Education) o;
        Question question = (Question) arg;
        System.out.println("===============================");
        System.out.println(name + "Hello, teacher!\n" +
                        "You have received a message from“" + education.getEduName() + ""I hope you can answer the following questions:\n" +
                        question.getContent() + "\n" +
                        "Questioner:" + question.getUserName());
    }
}

Test the main method:

 public static void main(String[] args) {

    Education edu = Education.getInstance();
    Teacher teacher1 = new Teacher("Kevin");
    Teacher teacher2 = new Teacher("Jhon");

    edu.addObserver(teacher1);
    edu.addObserver(teacher2);

    Question question = new Question();
    question.setUserName("Xiaofang");
    question.setContent("What are the application scenarios of observer mode?");

    edu.publishQuestion(question);

}

Test run results:

2, The embodiment of observer pattern in source code

2.1 ContextLoaderListener in spring

The ContextLoaderListener in Spring implements the ServletContextListener interface, and the ServletContextListener inherits the EventListener. Let's look at the source code of ContextLoaderListener:

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    public ContextLoaderListener() {
    }

    public ContextLoaderListener(WebApplicationContext context) {
        super(context);
    }

    public void contextInitialized(ServletContextEvent event) {
        this.initWebApplicationContext(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
        this.closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}

ServletContextListener :

public interface ServletContextListener extends EventListener {
    default void contextInitialized(ServletContextEvent sce) {
    }

    default void contextDestroyed(ServletContextEvent sce) {
    }
}

EventListener :

/**
 * A tagging interface that all event listener interfaces must extend.
 * @since JDK1.1
 */
public interface EventListener {
}

2.2 implementation of observer pattern based on Guava API

pom dependence

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

To create a listening event GuavaEvent:

public class GuavaEvent {

    @Subscribe
    public void subscrible(String str) {
        System.out.println("implement subscrible Method, the parameters passed in are:" + str);
    }

}

Test the main method:

public static void main(String[] args) {

    EventBus eventBus = new EventBus();
    GuavaEvent guavaEvent = new GuavaEvent();
    eventBus.register(guavaEvent);
    eventBus.post("Kevin");

}

3, Advantages and disadvantages of observer model

Advantage:

  • There is an abstract coupling between the observer and the observed;

  • Observer mode supports broadcast communication.

Disadvantages:

  • There is too much detail dependence between observers, which increases the time consumption and the complexity of the program;

  • Use properly and avoid circular calls.

Posted by scs on Sun, 01 Mar 2020 02:44:37 -0800