《图解设计模式》读书笔记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. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
随机推荐
- SpringMVC源码解析
一:springmvc运行过程: 1. dispatcherServlet 通过 HandlerMapping 找到controller2. controller经过后台逻辑处理得到结果集modela ...
- 在Visual studio 2017中使用EF6连接MySQL
在Visual studio 2017中使用EF6连接Mysql ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) ...
- Socket通讯-C#客户端与Java服务端通讯(发送消息和文件)
设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能. Java服务端设计 packag ...
- listalias - 列出用户和系统别名
总揽 listalias [ -s | -u ] [ 正则表达式] 描述 Listalias 按用户及系统别名每个输出一行.每行具有下列格式: <别名> <地址> (<注 ...
- poj 3714 Raid(平面最近点对)
Raid Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7473 Accepted: 2221 Description ...
- KeSetEvent
KeSetEvent https://bbs.pediy.com/ dll inject dll注入
- Docker 内pip安装package报错: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'
说来奇幻(对本菜来说, 经常遇到堪称奇幻的问题) 之前在docker里面各种安装都没问题, 也不知道什么引起的, 昨天晚上调试的时候卸载了一个包的版本,然后就安不上了. 宿主机安装依然各种流畅,唯独d ...
- uoj207 共价大爷游长沙 子树信息 LCT + 随机化 + 路径覆盖
题目传送门 http://uoj.ac/problem/207 题解 如果是一棵静态的树,有一个非常容易想到的算法:统计一下目前的每一个条边被几条路径经过,如果 \(x\) 到 \(y\) 的边的这个 ...
- DevExpress v19.1新版亮点——WinForms篇(一)
行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...
- 从1G到5G,移动通信发展之路
2G取代1G是历史的必然,诺基亚是2G时代的领航者. 3G是个“半吊子”系统,2G手机只能打电话.发短信,上网很困难.3G的通信标准将信息的传输率提高了一个数量级,这是一个飞跃,它使得移动互联网得以实 ...