观察者模式学习笔记(详细)
观察者模式学习笔记(详细)
一、什么是观察者模式
观察者模式,是定义对象之间的一对多的关系,主要作用是减少对象之间的耦合度,分为两个角色
- 被观察者:其实就是发布者,发布消息通知所有的观察者
- 观察者:接到被观察者发布的消息做出相应的动作
上图中,左边一组是被观察者,右边一组是观察者
Subjecct:被观察者抽象类,拥有类成员ObserverList,和三个抽象方法
ObserverList:存放所有的观察者对象
addObserver():向ObserverList中添加观察者对象
delObject():从ObserverList中删除观察者对象
notifyObservers():通知所有的观察者对象SubjectItem:具体的被观察者类,继承Subject接口,有具体的动作方法,调用父类的notifyObject()方法通知所有的观察者
Observer:观察者接口,有一个抽象方法update(),供被观察者调用
ObserverItem:具体的观察者类,实现Observer类,实现update()方法
二、使用场景
游戏中,被观察者主角有所动作就通知观察者们
支付中,一个商品购买成功,需要执行许多操作(更新订单,发送邮件,更新账户…),这时就可以使用观察者模式来减少耦合
再比如,关注动态,动态更新,需要发送通知给所有的关注者
三、具体实现
简单的一个冒险游戏,勇者做为被观察者,观察者有怪物,食物,NPC
当勇者移动碰到怪物时血量减1,碰到食物时血量加1,碰到NPC时展开剧情
- 编写Observer接口
public interface Observer {public void update();}
- 编写Subject抽象类
public abstract class Subject {//观察者集合private List<Observer> observerList = new ArrayList<>();//添加观察者public void addObserver(Observer observer){observerList.add(observer);}//删除观察者public void delObserver(Observer observer){observerList.remove(observer);}//通知所有观察者public void notifyObservers(){for(Observer observer : observerList){observer.update();}}}
observerList集合存放了观察者接口,不直接存放观察者类
notifyObservers()方法遍历observerList集合,调用update()方法
通过抽象层减少耦合
- 编写勇者类(被观察者)
public class Hero extends Subject {static int X = 0;static int Y = 0;//勇者移动public void move(int x, int y){X = x;Y = y;super.notifyObservers();}}
Hero类有move()方法,让勇者移动并调用父类的notifyObservers()方法通知所有的观察者
- 编写怪物类(观察者)
public class Monster implements Observer {static int X = 5;static int Y = 7;@Overridepublic void update() {if(Hero.X == X && Hero.Y == Y){System.out.println("怪物攻击勇者!");}}}
Monster类实现Observer接口,实现具体的update()方法
- 编写食物类(观察者)
public class Food implements Observer {static int X = 8;static int Y = 8;@Overridepublic void update() {if(Hero.X == X && Hero.Y == Y){System.out.println("勇者吃到了食物,血量加1!");}}}
Food类实现Observer接口,实现具体的update()方法
- 编写npc类(观察者)
public class Npc implements Observer {static int X = 15;static int Y = 20;@Overridepublic void update() {if(Hero.X == X && Hero.Y == Y){System.out.println("勇者遇到NPC,剧情展开!");}}}
Npc类实现Observer接口,实现具体的update()方法
- 编写执行类
public class Run {public static void main(String[] args){//初始化对象Hero hero = new Hero();Monster monster = new Monster();Food food = new Food();Npc npc = new Npc();//添加观察者hero.addObserver(monster);hero.addObserver(food);hero.addObserver(npc);//勇者移动,遇到怪物hero.move(5,7);//勇者移动,吃到食物hero.move(8,8);//勇者移动,遇到npchero.move(15,20);}}
勇者移动时通知了所有已注册的观察者,执行各自的update方法
- 运行结果
四、总结
优点:
使用抽象的方式来减少被观察者和观察者之间的耦合,可以方便的增加观察者缺点:
如果被观察者有过多的直接观察者和间接观察者的话,会花费更多的时间,如果观察者之间存在循环依赖的话,会导致他们直接进行循环调用,最终导致系统崩溃
观察者可以知道被观察者发生的变化,但是无法知道被观察者是如何发生的变化
观察者模式学习笔记(详细)相关推荐
- HTML入门学习笔记+详细案例
✨HTML入门学习笔记+详细案例 作者介绍:
- CTFHUB http协议题目 学习笔记 详细步骤 请求方式 302跳转 cookie 基础认证 响应源代码
CTFHUB http协议题目 学习笔记 详细步骤 请求方式 302跳转 cookie 基础认证 响应源代码 WEB-HTTP协议 1-请求方式 2-302跳转 3.cookie 4.基础认证 5.响 ...
- 设计模式之观察者模式学习笔记
前言 观察者模式,又叫作发布-订阅模式.一般的特点为对象间的关系为一对多,当一个对象被修改的时候,就会通知它依赖的对象 定义 定义对象间一种一对多的依赖关系,每当一个对象状态发生改变时,所有依赖于它的 ...
- python入门学习笔记——详细基础知识篇(第10章 正则表达式(重点)与JSON)
第10章 正则表达式(重点)与JSON 初识正则表达式 元字符与普通字符 字符集 概括字符集 数量词 贪婪与非贪婪 匹配0次1次或者无限多次 边界匹配符(^ .$) 组 匹配模式参数 re.sub正则 ...
- Linux线程互斥学习笔记--详细分析
一.互斥锁 为啥要有互斥? 多个进程/线程执行的先后顺序不确定,何时切出CPU也不确定. 多个进程/线程访问变量的动作往往不是原子的. 1. 操作步骤 (1)创建锁 // 创建互斥锁mutex pth ...
- Scala学习笔记-详细记录学习中遇到的知识点
目录 输入 print输出 变量 数据类型 标识符与关键字 运算符优先级 if else for循环 yield生成器 break与continue 函数 局部函数 惰性lazy 异常 类与对象 构造 ...
- malloc 源码_【C++学习笔记(九)】之 new运算符的使用/ new 与 malloc的异同(附代码,详细注释)...
new 运算符的使用 一. new的简单介绍: new运算符用于在堆区开辟空间,所有new出来的对象,对返回该类对象的指针. 二. new 与 malloc 的异同点: 1.malloc作用相同, m ...
- Linux 学习笔记之超详细基础linux命令 Part 3
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 2----------------- ...
- JUC.Condition学习笔记[附详细源码解析]
JUC.Condition学习笔记[附详细源码解析] 目录 Condition的概念 大体实现流程 I.初始化状态 II.await()操作 III.signal()操作 3个主要方法 Conditi ...
最新文章
- SVO 学习笔记(深度滤波)
- FILE文件流的中fopen、fread、fseek、fclose的使用
- 抖音小程序微信小程序五角星型评分插件自定义分数组件
- 数据结构:最大子序列和
- 用计算机弹没那种命,成熟小女人QQ个性网名 没那种命就别犯那种病
- 第25天多线程、网络编程
- JAVA 网络编程小记
- InfluxDB(官方使用说明)
- cover-letter
- SAP License:SAP财务管理的认识
- Rust : 宏、重复、及向量与递归实例
- linux系统清空文件内容
- 用友U8案例教程财务报表
- Webservice 学习笔记
- 金山词霸PC企业版2016
- Composer加载的symfony/var-dumper类库 字体大小样式设置
- C语言switch语句无break
- 初中计算机数学,初中数学
- Fater RCNN 试着加入注意力机制模型
- 使用 Python 进行数据预处理的标准化