文章目录
1.什么是观察者模式
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
2.观察者模式应用场景
- Zookeeper事件通知节点
- 消息订阅通知
- 安卓开发事件注册
- 分布式配置中心
3.观察者模式原理类图
- 抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
- 抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- 具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
- 具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
4.观察者模式简单的实现
4.1 抽象主题
public interface AbstractSubject {
/**
* 添加观察者 注册观察者
*/
void addObServer(ObServer obServer);
/**
* 移除观察者
*
* @param obServer
*/
void removeServer(ObServer obServer);
/**
* 通知消息
*/
void notifyObServer(String message);
}
4.2 抽象观察者
public interface ObServer {
/**
* 通知观察者消息
*
* @param message
*/
void update(String message);
}
4.3 具体主题
public class WeChatSubject implements AbstractSubject {
/**
* 如何存放这些主题
* @param obServer
*/
private List<ObServer> obServerList = new ArrayList<ObServer>();
public void addObServer(ObServer obServer) {
// 注册或者添加观察者
obServerList.add(obServer);
}
public void removeServer(ObServer obServer) {
obServerList.remove(obServer);
}
public void notifyObServer(String message) {
System.out.println("开始设置微信群发消息:" + message);
// 调用观察者通知方案
for (int i = 0; i < obServerList.size(); i++) {
ObServer obServer = obServerList.get(i);
// 调用该方法通知 获取具体的消息 群发
obServer.update(message);
}
}
}
4.4 具体观察者
public class UserObServer implements ObServer {
private String name;
public UserObServer(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + ",收到微信服务通知的消息:" + message);
}
}
4.5 测试方法
public class SimpleTest {
public static void main(String[] args) {
// 1.创建具体的在主题
AbstractSubject abstractSubject = new WeChatSubject();
// 2.开始注册或者添加观察者
abstractSubject.addObServer(new UserObServer("aric"));
abstractSubject.addObServer(new UserObServer("ann"));
// 3.群发消息
abstractSubject.notifyObServer("沐宇熙设计模式");
}
}
5.JDK自带观察实现消息发送
- Observable类追踪所有的观察者,并通知他们。
- Observer这个接口看起来很熟悉,它和我们之前写的类几乎一样。
5.1 案例
用户下单成功后会发送短信、发送邮件、发送微信
5.1.1 具体主题
public class MessageObServable extends Observable {
@Override
public void notifyObservers(Object arg) {
// 1.修改状态为可以群发
setChanged();
// 2.调用父类的notifyObservers 群发消息
super.notifyObservers(arg);
}
}
5.1.2 具体观察者
public class EmailObServer implements Observer {
public void update(Observable o, Object arg) {
System.out.println("用户下单成功,发送邮件提醒内容:" + arg);
}
}
public class SmsObServer implements Observer {
public void update(Observable o, Object arg) {
System.out.println("用户下单成功,发送短信提醒内容:" + arg);
}
}
public class WechatObServer implements Observer {
public void update(Observable o, Object arg) {
System.out.println("用户下单成功,发送微信体醒内容:" + arg);
}
}
5.1.3 测试方法
public class TestJdkObServer {
public static void main(String[] args) {
// 1.创建具体的主题
Observable observable = new MessageObServable();
// 2. 注册观察者
observable.addObserver(new SmsObServer());
observable.addObserver(new WechatObServer());
observable.addObserver(new EmailObServer());
// 3.群发消息
observable.notifyObservers("沐宇熙设计模式");
}
}
6.Spring封装事件监听
Spring实现事件通知,底层才观察者模式封装的
6.1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
6.2 主题类
@Data
public class OrderMessageEvent extends ApplicationEvent {
/**
* 群发消息的内容
*/
private JSONObject jsonObject;
/**
* Create a new ApplicationEvent.
* @param source the object on which the event initially occurred (never {@code null})
*/
public OrderMessageEvent(Object source, JSONObject jsonObject) {
super(source);
this.jsonObject = jsonObject;
}
}
6.3 具体监听类
@Component
public class EmailListener implements ApplicationListener<OrderMessageEvent> {
@Override
@Async
public void onApplicationEvent(OrderMessageEvent event) {
//如何获取到当前容器下面所有的观察者呢?反射机制获取ApplicationListener 接口下面子类
System.out.println(Thread.currentThread().getName()+"开始发送邮件消息内容:" + JSONUtil.toJsonStr(event.getJsonObject()));
}
@Component
public class SmsListener implements ApplicationListener<OrderMessageEvent> {
@Override
@Async
public void onApplicationEvent(OrderMessageEvent event) {
System.out.println(Thread.currentThread().getName() + "开始短信消息内容:" + JSONUtil.toJsonStr(event.getJsonObject()));
}
}
6.4 控制类
@RestController
public class OrderController {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping("/sendMsg")
public String sendMsg() {
//1.定义发送消息内容
JSONObject jsonObject = new JSONObject();
jsonObject.put("email", "599982811@qq.com");
jsonObject.put("phone", "18888888888");
jsonObject.put("text", "设计模式");
OrderMessageEvent orderMessageEvent = new OrderMessageEvent(this, jsonObject);
applicationContext.publishEvent(orderMessageEvent);
return "success";
}
}
6.5 启动类
@SpringBootApplication
@EnableAsync
public class AppObServer {
public static void main(String[] args) {
SpringApplication.run(AppObServer.class);
}
}