Java中常用的设计模式之观察者模式详解
作者:Asurplus、 发布时间:2023-07-27 12:32:52
标签:Java,设计模式,观察者模式
优点
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
0
投稿
猜你喜欢
- 这篇文章主要介绍了Spring @Transactional注解失效解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- 主题 ActiveMQ Spring Boot 小程序开发1.引入依赖<parent><groupId>org.sp
- 概述企业内部一般都有一套单点登录系统(常用的实现有apereo cas),所有的内部系统的登录认证都对接它。本文介绍spring boot的
- 一、对AOP的初印象首先先给出一段比较专业的术语:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向
- 在实际应用中,我们往往有需要比较两个自定义对象大小的地方。而这些自定义对象的比较,就不像简单的整型数据那么简单,它们往往包含有许多的属性,我
- 登录接口实现public User queryUser(String UserName, String Password,HttpServl
- 本文实例讲述了Java实现的不同图片居中剪裁生成同一尺寸缩略图功能。分享给大家供大家参考,具体如下:因为业务需要,写了这样一个简单类,希望能
- 本文实例为大家分享了Unity使用鼠标旋转物体效果的具体代码,供大家参考,具体内容如下了解完基础知识后,然我们来做个小程序练习一下1.在Ma
- 本文实例讲述了C#实现身份证号码验证的方法。分享给大家供大家参考。具体实现方法如下:随着现在互联网的发展,越来越多的注册用户的地方都用到了身
- Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项
- 本文研究的主要是Java中finally和return的关系,具体介绍和实例如下所示。finally 和 return 关系的总结1.try
- 命令仓库 Ctrl + Shift + A 可以搜集对应命令快捷键1、基础快捷键1.1、无处不在的跳转项目之间的跳转1.1.1、项目项目之间
- jar 包启动时指定配置文件 application.ymlnohup java -jar vPaas.jar --spring.confi
- 引用Spring官方文档的说法介绍一下@Conditional注解:Spring5.0.15版本@Conditional注解官方文档@Con
- 笔记在微服务中,若想要使用远程调用,需要引入spring-cloud-starter-openfeign(在使用注册中心的环境下)<d
- java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用
- Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持。Acegi是基于Spring IOC 和 AO
- 一、延迟加载:LazyLoading使用延迟加载,关联的实体必须标注为virtual。本例是标注Destination类里的Lodgings
- 1.问题由来迷宫实验是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒中设置了许多墙,对行进方向形成了多处阻挡
- 前提说明之前公司有一个项目是由androidstudio接入高德地图实现导航,定位等功能,然后还有一部分登陆页面和其他逻辑都放在Unity方