Java中常用的设计模式之观察者模式详解
作者:Asurplus、 时间:2023-07-27 12:32:52
优点
1.观察者和被观察者是抽象耦合的。
2.建立一套触发机制。
缺点
1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2.如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3.观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景
一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
注意事项
1.JAVA 中已经有了对观察者模式的支持类。
2.避免循环引用。
3.如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
一、实现方式
1、观察者抽象类
package com.asurplus.common.observe;
/**
* 观察者
*/
public abstract class Observer {
protected Subject subject;
/**
* 发布事件
*/
public abstract void update();
}
2、第一个观察者
package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer1 extends Observer {
public Observer1(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
log.info("观察者 1 收到通知:{}", this.subject.getState());
}
}
3、第二个观察者
package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer2 extends Observer {
public Observer2(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
log.info("观察者 2 收到通知:{}", this.subject.getState());
}
}
4、第三个观察者
package com.asurplus.common.observe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Observer3 extends Observer {
public Observer3(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
log.info("观察者 3 收到通知:{}", this.subject.getState());
}
}
5、定义主题
package com.asurplus.common.observe;
import java.util.ArrayList;
import java.util.List;
/**
* 主题
*/
public class Subject {
/**
* 观察者列表
*/
private List<Observer> observers = new ArrayList<>();
/**
* 标志
*/
private int state;
public int getState() {
return state;
}
/**
* 标识被改变
*
* @param state
*/
public void setState(int state) {
this.state = state;
// 通知所有观察者
notifyAllObservers();
}
/**
* 添加进接收者列表
*
* @param observer
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* 通知所有人被改变
*/
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
类似于消息发布一样,有多个接收者,当标志位被改变的时候,通知多个接收者。
二、测试
package com.asurplus.common.observe;
public class TestMain {
public static void main(String[] args) {
// 创建主题
Subject subject = new Subject();
// 添加观察者
new Observer1(subject);
new Observer2(subject);
new Observer3(subject);
// 改变标志
subject.setState(10);
}
}
输出结果
可以看出,三个接收者都收到了事件通知,从而实现了我们的观察者模式。
来源:https://lizhou.blog.csdn.net/article/details/123151882
标签:Java,设计模式,观察者模式
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Spring从@Aspect到Advisor使用演示实例
2022-11-21 11:42:08
C#通过属性名字符串获取、设置对象属性值操作示例
2022-01-06 14:28:08
Java分形绘制山脉模型
2023-05-10 00:51:29
![](https://img.aspxhome.com/file/2023/1/80901_0s.jpg)
java基础知识之FileInputStream流的使用
2021-07-05 00:30:24
![](https://img.aspxhome.com/file/2023/6/104036_0s.jpg)
基于C#模拟实现回合制游戏
2021-08-01 23:09:55
![](https://img.aspxhome.com/file/2023/8/113808_0s.png)
flutter使用tauri实现一个一键视频转4K软件
2022-10-23 05:46:42
Java动态代理模式的深入揭秘
2023-07-27 23:41:25
![](https://img.aspxhome.com/file/2023/9/113249_0s.jpg)
带你了解mybatis如何实现读写分离
2023-07-29 14:26:28
Struts2返回json格式数据代码实例
2023-10-12 13:15:32
Java访问WebService返回XML数据的方法
2023-11-10 21:23:09
C# using()的使用方法
2022-03-02 23:23:37
![](https://img.aspxhome.com/file/2023/0/76400_0s.png)
java实现简单的图书管理系统
2022-11-25 03:30:11
![](https://img.aspxhome.com/file/2023/8/61778_0s.png)
SWT(JFace) Menu、Bar...体验代码
2022-01-29 08:34:46
C#泛型的使用及示例详解
2022-03-14 07:01:59
![](https://img.aspxhome.com/file/2023/0/89760_0s.png)
Swing常用组件之多行文本区JTextArea
2023-11-08 14:16:49
@Autowired注解注入的xxxMapper报错问题及解决
2022-10-01 10:31:02
![](https://img.aspxhome.com/file/2023/5/63635_0s.jpg)
详解J2EE开发的网站部署到阿里云服务器的方法
2022-06-21 07:50:16
![](https://img.aspxhome.com/file/2023/9/64959_0s.jpg)
springboot+spring data jpa实现新增及批量新增方式
2023-01-27 03:45:53
OpenCV实现简单摄像头视频监控程序
2021-12-10 01:23:07
基于C#调用OCX控件的常用方法(推荐)
2021-06-24 11:56:29
![](https://img.aspxhome.com/file/2023/9/79099_0s.png)