观察者模式
概述
观察者模式(Observer Pattern)定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己属于行为型模式。观察者模式有时也叫发布-订阅模式。观察者模式主要用于在关联者之间建立一套触发机制的场景。生活中也有类似场景比如微信朋友圈动态通知、邮件通知、广播通知等等。
看下类图
看一下简单的观察者模式实现
抽象主题类
public abstract class Subject { private List<Observer> observers = new ArrayList<Observer>(); public void attach(Observer observer) { observers.add(observer); } public void detch(Observer observer) { observers.remove(observer); } public void notifyObserver() { for (Observer observer:observers) { observer.update(); } } }
抽象观察者接口
public interface Observer { public abstract void update(); }
具体主题类
public class ConcreteSubject extends Subject{ private String subjectState; public String getSubjectState() { return subjectState; } public void setSubjectState(String subjectState) { this.subjectState = subjectState; } }
具体观察者
public class ConcreteObserver implements Observer { private String name; private ConcreteSubject subject; public ConcreteObserver(String name, ConcreteSubject subject) { this.name = name; this.subject = subject; } @Override public void update() { System.out.println("观察者" + name + "通知信息:"+ subject.getSubjectState()); } }
测试类
public class Client { public static void main(String[] args) { ConcreteSubject s = new ConcreteSubject(); s.attach(new ConcreteObserver("X",s)); s.attach(new ConcreteObserver("Y",s)); s.setSubjectState("ABC"); s.notifyObserver(); } }
结果
其实JDK本身也提供了观察者模式的API,下面利用JDK提供的观察者模式API,编写一个在某平台上提交问题通知老师的例子
某教育平台(被观察者继承Observable )
public class EduForum extends Observable { private String name = "XX教育论坛"; private static EduForum eduForum = null; private EduForum(){} public String getName() { return name; } public static EduForum getInstance() { if (eduForum == null) eduForum = new EduForum(); return eduForum; } public void publichQuestion(Question question) { System.out.println(question.getUsername()+ "在" + this.name + "上提交一个问题"); setChanged(); notifyObservers(question); } }
问题类
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; } @Override public void update(Observable o, Object arg) { EduForum eduForum = (EduForum) o; Question question = (Question) arg; System.out.println("==============================="); System.out.println(this.name + "老师,收到一个来自" + eduForum.getName() + "的一个问题,\n内容是:" + question.getContent() + "\n提问者是:" + question.getUsername()); } }
测试类
public class Client { public static void main(String[] args) { EduForum eduForum = EduForum.getInstance(); Teacher zhao = new Teacher("张三"); Teacher li = new Teacher("李四"); eduForum.addObserver(zhao); eduForum.addObserver(li); Question question = new Question(); question.setUsername("小明"); question.setContent("观察者模式适用哪些场景?"); eduForum.publichQuestion(question); } }
结果