观察者模式又叫做发布-订阅模式、模型-视图模式、源-监听器,模式或从属者模式。定义一种一对多的依赖关系,一个主题对象可被java
多个观察者对象同时监听,使得每当主题对象状态变化时,全部依赖它的对象都会获得通知并自动更新,属于行为型设计模式。设计模式
观察者模式的UML类图:跨域
由上图能够看到观察者模式包含4个角色。异步
当小伙伴们在GPer生态圈中提问时,若是有设置指定的老师回答,则对应的老师就会收到邮件通知,这就是观察者模式的一种应用场景。测试
有些小伙伴可能会想到用mq、异步队列等,其实JDK自己就提供这样的API。咱们用代码来还原这样一个应用场景,首先建立GPer类。this
/** * 被观察者 */ public class GPer extends Observable { private String name = "GPer生态圈"; private static final GPer gper = new GPer(); private GPer() {} public static GPer getInstance(){ return gper; } public String getName() { return name; } public void publishQuestion(Question question){ System.out.println(question.getUserName() + "在" + this.name + "上提交了一个问题。"); setChanged(); notifyObservers(question); } }
而后建立问题Question类。spa
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; } }
接着建立观察者老师类。设计
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 + "老师,你好!\n" + "您收到了一个来自" + gper.getName() + "的提问,但愿您解答。问题内容以下:\n" + question.getContent() + "\n" + "提问者:" + question.getUserName()); } }
最后编写客户端测试代码。code
public class Test { 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); //用户行为 Question question = new Question(); question.setUserName("张三"); question.setContent("观察者模式适用于哪些场景?"); gper.publishQuestion(question); } }
Observable类是JDK自带的被观察者类,咱们能够经过继承的方式实现本身的业务,经过addObserver方法能够添加多个观察者,当咱们发生改变时server
设置状态为改变,而后再调用notifyObservers调用添加进来的全部的观察者。