《图解设计模式》读书笔记8-1 Observer模式
Observer模式即观察者模式,该模式中,被观察者的状态发生变化后会通知给观察者。
此模式适用于根据对象状态进行处理的场景。
示例程序
下面代码的功能是:被观察者是一个随机数生成器,有两个观察者,分别以数值形式和图示形式展示被观察者生成的数字。
程序类图

程序
抽象的数字生成器
public abstract class NumberGenerator {
//观察者列表
private ArrayList observers = new ArrayList();
//增加观察者
public void addObserver(Observer observer) {
observers.add(observer);
}
//删除观察者
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
//提醒观察者
public void notifyObservers() {
Iterator it = observers.iterator();
while (it.hasNext()) {
Observer o = (Observer)it.next();
o.update(this);
}
}
public abstract int getNumber();
public abstract void execute();
}
具体的数字生成器
执行execute()方法后通知观察者
public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
public int getNumber() {
return number;
}
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
notifyObservers();
}
}
}
观察者接口
public interface Observer {
void update(NumberGenerator generator);
}
观察者(数字形式展示)
public class DigitObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
观察者(图形方式展示)
public class GraphObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
int count = generator.getNumber();
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println("");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
执行
public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
//结果
DigitObserver:22
GraphObserver:**********************
DigitObserver:11
GraphObserver:***********
DigitObserver:40
GraphObserver:****************************************
DigitObserver:39
GraphObserver:***************************************
DigitObserver:28
GraphObserver:****************************
DigitObserver:23
GraphObserver:***********************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:39
GraphObserver:***************************************
......省略
角色和类图
角色
- Subject:被观察者
被观察者内部维护了一个观察者的list,定义了增加和删除观察者的方法。同时还定义了一个通知观察者的方法,作用是:如果自己内部发生了变化,通知观察者取得这些变化。本例中由NumberGenerator扮演这个角色。
- ConcreteSubject:具体的被观察者
实现了被观察者的执行方法,在执行过程中调用方法通知观察者。本例中由RandomNumberGenerator扮演此角色。
- Observer:观察者
声明供被观察者调用的方法,此方法可以获得被观察者状态的变化值。本例中由Observer接口扮演此角色。
- ConcreteObserver:具体的观察者
实现了观察者接口的方法,通过这个方法可以获得被观察者的值,达到监控的目的。本例中由DigitObserver和GraphObserver扮演此角色。
类图

思路拓展
可复用性
对于具体的被观察者和观察者而言,他们之间的关系由他们的父类和接口进行关联。
具体的被观察者RandomNumberGenerator不需要知道观察者是谁,有多少,它只负责执行时调用通知方法通知观察者即可。
具体的观察者GraphObserver和DigitObserver不需要知道是谁实现了NumberGenerator,只负责拿到值并处理即可。
这样的设计降低了耦合度,提升组件可复用性。其做法的特点是:
利用抽象类和接口从具体类中抽出抽象方法。
将实例作为参数传递至类中,或者在类的字段中保存实例时,不使用具体类型,而是使用抽象类型和接口。
Observer的顺序
如果观察者能够改变被观察者的数据,那就要注意观察者的调用顺序了。还要注意防止循环调用
当Subject发生变化时,通知Observer,Observer改变Subject,Subject发生变化,通知Observer...
MVC模式
Model发生改变时通知View,View根据Model的值显示新的内容。Model就是被观察者,View就是观察者。
《图解设计模式》读书笔记8-1 Observer模式的更多相关文章
- HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...
- HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern)
观察者模式:定义了对象之间一对多的依赖关系,这样一来,当一个对象的状态发生改变时,它的依赖者将会受到通知并且自动更新. 有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事,对象甚至在运行时可以 ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- Head First 设计模式读书笔记(1)-策略模式
一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...
- JavaScript设计模式:读书笔记(未完)
该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...
- Head First设计模式读书笔记
阅读指南: 精读一章内容,手工输入一章代码(注1),与书中描述的思想进行印证,实在搞不懂就放过吧.设计模式绝对不会一次就看懂的. 这本书对于理解设计模式很有帮助,就是例子不太符合中国人的思维模式,但是 ...
- 图解http读书笔记
以前对HTTP协议一知半解,一直不清楚前端需要对于HTTP了解到什么程度,知道接触的东西多了,对于性能优化.服务端的配合和学习中也渐渐了解到了HTTP基础的重要性,看了一些大神对HTTP书籍的推荐,也 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
随机推荐
- TMS320F28335——SCI串口
一.IO配置 以SCIA为例:使用的是GPIO35--SCITXDA GPIOA36--SCIRXDA 使用寄存器: GPBPUD :设置上拉 GPIO32-GPIO63 对应位0 使能上 ...
- Docker:删除images报错(Error response from daemon: conflict: unable to delete 6885a5e3712a (must be forced) - image is being used by stopped container 0cf27d7d29c7)
1.进入root权限 sudo su 2.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有contain ...
- java中的数据类型,基本数据类型及其包装类型
java中的8大基本类型及其包装类型 1,int--->Integer 2,byte--->Byte 3,short--->Short 4,long--->Long 5,cha ...
- Python multiprocessing使用详解
multiprocessing包是Python中的多进程管理包. 与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程. 该进程可以运行在 ...
- 认识一下Qt用到的开发工具
http://c.biancheng.net/view/3868.html Qt 不是凭空产生的,它是基于现有工具链打造而成的,它所使用的编译器.链接器.调试器等都不是自己的,Qt 官方只是开发了上层 ...
- 搭建jumperserver堡垒机管理万台服务器-1
搭建jumperserver堡垒机管理万台服务器-1 1 Jumpserver堡垒机概述-部署Jumpserver运行环境 2 安装Coco组件 3 安装Web-Terminal前端-Luna组 ...
- ST7735和ST7789驱动
/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #de ...
- 动态路由协议RIP
RIP Routing Information Protocol,属IGP协议,是距离矢量型动态路由协议(直接发送路由信息的协议为距离矢量型协议),使用UDP协议,端口号520. 贝尔曼福特算法 RI ...
- 001-supervisor
supervisor 使用教程(转) 原文地址:https://word.gw1770df.cc/2016-08-04/linux/supervisor-%E4%BD%BF%E7%94%A8%E6%9 ...
- tee 多重定向
1.命令功能 tee读取标准输入的数据,并将内容输出成文件. 2.语法格式 tee option file tee [-ai] 文件 参数说明 参数 参数说明 -a 追加到文件后面,非覆盖 - ...