博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
522还不知道怎么表白吗?——经典设计模式之【观察者模式】
阅读量:6274 次
发布时间:2019-06-22

本文共 6526 字,大约阅读时间需要 21 分钟。

hot3.png

写在前面:设计模式源于生活,而又高于生活!

什么是观察者模式

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象收到通知并自动更新

其实就是发布订阅模式,发布者发布消息,订阅者获取消息,订阅了就能收到消息,没订阅就收不到消息。

观察者模式应用场景

Zookeeper事件通知节点、消息订阅通知、安卓开发事件注册

观察者模式原理类图

235acc6adf8c1ecf6ae441aeff538a099ea.jpg

抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。

具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。

观察者模式实现方式一

抽象观察者

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 List
listObServer = 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“}

版权

本文参考:蚂蚁课堂:

转载于:https://my.oschina.net/u/3995125/blog/3052420

你可能感兴趣的文章
input checkbox 复选框大小修改
查看>>
网吧维护工具
查看>>
BOOT.INI文件参数
查看>>
vmstat详解
查看>>
新年第一镖
查看>>
unbtu使用笔记
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
Android程序开发初级教程(一) 开始 Hello Android
查看>>
使用Gradle打RPM包
查看>>
“我意识到”的意义
查看>>
淘宝天猫上新辅助工具-新品填表
查看>>
再学 GDI+[43]: 文本输出 - 获取已安装的字体列表
查看>>
nginx反向代理
查看>>
操作系统真实的虚拟内存是什么样的(一)
查看>>
hadoop、hbase、zookeeper集群搭建
查看>>
python中一切皆对象------类的基础(五)
查看>>
modprobe
查看>>
android中用ExpandableListView实现三级扩展列表
查看>>
%Error opening tftp://255.255.255.255/cisconet.cfg
查看>>
java读取excel、txt 文件内容,传到、显示到另一个页面的文本框里面。
查看>>