写在前面:设计模式源于生活,而又高于生活!
什么是观察者模式
在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象收到通知并自动更新
其实就是发布订阅模式,发布者发布消息,订阅者获取消息,订阅了就能收到消息,没订阅就收不到消息。
观察者模式应用场景
Zookeeper事件通知节点、消息订阅通知、安卓开发事件注册
观察者模式原理类图
抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
观察者模式实现方式一
抽象观察者
public interface ObServer { /** * 更新消息内容 */ public void update(String message);}
抽象主题者
public interface AbstractSubject { /** * 添加obServer */ void addObServer(ObServer obServer); /** * 移除obServer */ void removeObServer(ObServer obServer); /** * 通知所有的notifyObServerAll */ void notifyObServerAll(String message); /** * 设置更新内容 */ void setNtifyMessage(String message);}
具体主题
public class WeChatSubject implements AbstractSubject { /** * 存放所有的ObServer */ private ListlistObServer = new ArrayList (); /** * 更新的内容 */ private String message; public void addObServer(ObServer obServer) { listObServer.add(obServer); } public void removeObServer(ObServer obServer) { listObServer.remove(obServer); } public void notifyObServerAll(String message) { for (int i = 0; i < listObServer.size(); i++) { ObServer obServer = listObServer.get(i); obServer.update(message); } } public void setNtifyMessage(String message) { this.message = message; System.out.println("微信公众号设置message:" + message); notifyObServerAll(message); }}
具体观察者
public class UserObServer implements ObServer { /** * 订阅者用户名称 */ private String name; /** * 发送内容 */ private String message; public UserObServer(String name) { this.name = name; } public void update(String message) { this.message = message; read(); } public void read() { System.out.println(name + "同学收到推送消息:" + message); }}
运行测试
public class App { public static void main(String[] args) { // 1.注册主题 AbstractSubject weChatSubject = new WeChatSubject(); // 2.添加观察者 订阅主题 weChatSubject.addObServer(new UserObServer("小须")); weChatSubject.addObServer(new UserObServer("小霞")); // 3.设置发送消息 weChatSubject.setNtifyMessage("消息内容:小须喜欢小霞"); }}
返回结果
微信公众号设置message:消息内容:小须喜欢小霞
小须同学收到推送消息:消息内容:小须喜欢小霞 小霞同学收到推送消息:消息内容:小须喜欢小霞
观察者模式实现方式二
JDK自带观察实现消息发送
(1). Observable类追踪所有的观察者,并通知他们。
(2). Observer这个接口看起来很熟悉,它和我们之前写的类几乎一样。
自定义主题
public class MessageObServable extends Observable { @Override public void notifyObservers(Object arg) { // 1.改变数据 setChanged(); // 2.通知所有的观察者改变 super.notifyObservers(arg); }}
自定义观察者
public class EmailObServer implements Observer { public void update(Observable o, Object arg) { // 1.获取主题 MessageObServable messageObServable = (MessageObServable) o; System.out.println("发送邮件内容:" + arg); }}public class SmsObServer implements Observer { public void update(Observable o, Object arg) { System.out.println("发送短信内容:" + arg); }}
运行监听开始
public class JdkObServer { public static void main(String[] args) { //1.创建主题 MessageObServable messageObServable = new MessageObServable(); // 2.添加订阅者 messageObServable.addObserver(new EmailObServer()); messageObServable.addObserver(new SmsObServer()); // 3.组装消息内容 JSONObject jsonObject = new JSONObject(); jsonObject.put("email", "11111111@qq.com"); jsonObject.put("phone", "11111111111"); jsonObject.put("text", "小须喜欢小霞."); messageObServable.notifyObservers(jsonObject.toJSONString()); }}
pom依赖
com.alibaba fastjson 1.2.30
结果
发送短信内容:{"phone":"11111111111","text":"小须喜欢小霞.","email":"11111111@qq.com"}
发送邮件内容:{"phone":"11111111111","text":"小须喜欢小霞.","email":"11111111@qq.com"}
观察者模式实现方式三
Spring封装事件监听
OrderCreateEvent
public class OrderCreateEvent extends ApplicationEvent { private JSONObject jsonObject; public OrderCreateEvent(Object source, JSONObject jsonObject) { super(source); this.jsonObject = jsonObject; } public JSONObject getJsonObject() { return jsonObject; } public void setJsonObject(JSONObject jsonObject) { this.jsonObject = jsonObject; }}
EmailListener
@Componentpublic class EmailListener implements ApplicationListener{ @Override @Async public void onApplicationEvent(OrderCreateEvent event) { System.out.println(Thread.currentThread().getName()+"发送邮件内容:" + event.getJsonObject().toJSONString()); }}
SmsListener
@Componentpublic class SmsListener implements ApplicationListener{ @Override @Async public void onApplicationEvent(OrderCreateEvent event) { System.out.println(Thread.currentThread().getName() + "发送短信内容:" + event.getJsonObject().toJSONString()); }}
controller
@RestControllerpublic class OrderController { @Autowired private ApplicationContext applicationContext; @RequestMapping("/sendMsg") public String sendMsg() { // 3.组装消息内容 JSONObject jsonObject = new JSONObject(); jsonObject.put("email", "11111111@qq.com"); jsonObject.put("phone", "11111111111"); jsonObject.put("text", "小须喜欢小霞."); OrderCreateEvent orderCreateEvent = new OrderCreateEvent(this, jsonObject); applicationContext.publishEvent(orderCreateEvent); return "success"; }}
AppStart
@SpringBootApplication@EnableAsyncpublic class AppStart { public static void main(String[] args) { SpringApplication.run(AppStart.class,args); }}
pom
org.springframework.boot spring-boot-starter-parent 2.0.1.RELEASE com.alibaba fastjson 1.2.30 org.springframework.boot spring-boot-starter-web
结果输出
SimpleAsyncTaskExecutor-2发送短信内容:{"phone":"11111111111","text":"小须喜欢小霞.","email":"11111111@qq.com"}
SimpleAsyncTaskExecutor-1发送邮件内容:{"phone":"11111111111","text":"小须喜欢小霞.","email":"11111111@qq.com“}
版权