《Java编程思想第四版》第 16 章 设计范式-提到观察者模式
在由Gamma,Helm 和 Johnson 编著的《Design Patterns》一书中被定义成一个“里程碑”。那本书列出了解决这个问题的 23 种不同的方法
16.1.2 范式分类
《Design Patterns》一书讨论了 23种不同的范式,并依据三个标准分类(所有标准都涉及那些可能发生变
化的方面)。这三个标准是:
(1) 创建:对象的创建方式。这通常涉及对象创建细节的隔离,这样便不必依赖具体类型的对象,所以在新
添一种对象类型时也不必改动代码。
(2) 结构:设计对象,满足特定的项目限制。这涉及对象与其他对象的连接方式,以保证系统内的改变不会
影响到这些连接。
(3) 行为:对程序中特定类型的行动进行操纵的对象。这要求我们将希望采取的操作封装起来,比如解释一
种语言、实现一个请求、在一个序列中遍历(就象在继承器中那样)或者实现一种算法。本章提供了“观察
器”(Observer)和“访问器”(Visitor)的范式的例子。
《Design Patterns》为所有这 23种范式都分别使用了一节,随附的还有大量示例,但大多是用 C++编写
的,少数用 Smalltalk 编写(如看过这本书,就知道这实际并不是个大问题,因为很容易即可将基本概念从
两种语言翻译到Java 里)。现在这本书并不打算重复《Design Patterns》介绍的所有范式,因为那是一本
独立的书,大家应该单独阅读。相反,本章只准备给出一些例子,让大家先对范式有个大致的印象,并理解
它们的重要性到底在哪里
16.1.1 单子
或许最简单的设计范式就是“单子”(Singleton),它能提供对象的一个(而且只有一个)实例。单子在
Java 库中得到了应用,但下面这个例子显得更直接一些:
//: SingletonPattern.java
// The Singleton design pattern: you can
// never instantiate more than one.
589
package c16;
// Since this isn't inherited from a Cloneable
// base class and cloneability isn't added,
// making it final prevents cloneability from
// being added in any derived classes:
final class Singleton {
private static Singleton s = new Singleton(47);
private int i;
private Singleton(int x) { i = x; }
public static Singleton getHandle() {
return s;
}
public int getValue() { return i; }
public void setValue(int x) { i = x; }
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton s = Singleton.getHandle();
System.out.println(s.getValue());
Singleton s2 = Singleton.getHandle();
s2.setValue(9);
System.out.println(s.getValue());
try {
// Can't do this: compile-time error.
// Singleton s3 = (Singleton)s2.clone();
} catch(Exception e) {}
}
} ///:~
创建单子的关键就是防止客户程序员采用除由我们提供的之外的任何一种方式来创建一个对象。必须将所有
构建器都设为private(私有),而且至少要创建一个构建器,以防止编译器帮我们自动同步一个默认构建
器(它会自做聪明地创建成为“友好的”——friendly,而非 private)。
此时应决定如何创建自己的对象。在这儿,我们选择了静态创建的方式。但亦可选择等候客户程序员发出一
个创建请求,然后根据他们的要求动态创建。不管在哪种情况下,对象都应该保存为“私有”属性。我们通
过公用方法提供访问途径。在这里,getHandle()会产生指向 Singleton 的一个句柄。剩下的接口(getValue()和 setValue())属于普通的类接口。
Java 也允许通过克隆(Clone)方式来创建一个对象。在这个例子中,将类设为 final 可禁止克隆的发生。
16.2 观察器范式(观察者)
观察器(Observer)范式解决的是一个相当普通的问题:由于某些对象的状态发生了改变,所以一组对象都
需要更新,那么该如何解决?在Smalltalk 的MVC(模型-视图-控制器)的“模型-视图”部分中,或在
几乎等价的“文档-视图结构”中,大家可以看到这个问题。现在我们有一些数据(“文档”)以及多个视
图,假定为一张图(Plot)和一个文本视图。若改变了数据,两个视图必须知道对自己进行更新,而那正是
“观察器”要负责的工作。这是一种十分常见的问题,它的解决方案已包括进标准的 java.util 库中。
在Java 中,有两种类型的对象用来实现观察器范式。其中,Observable 类用于跟踪那些当发生一个改变时
希望收到通知的所有个体——无论“状态”是否改变。如果有人说“好了,所有人都要检查自己,并可能要
进行更新”,那么Observable 类会执行这个任务——为列表中的每个“人”都调用 notifyObservers()方
法。notifyObservers()方法属于基础类Observable 的一部分。
在观察器范式中,实际有两个方面可能发生变化:观察对象的数量以及更新的方式。也就是说,观察器范式
允许我们同时修改这两个方面,不会干扰围绕在它周围的其他代码。
下面这个例子类似于第 14章的ColorBoxes 示例。箱子(Boxes)置于一个屏幕网格中,每个都初始化一种随
机的颜色。此外,每个箱子都“实现”(implement)了“观察器”(Observer)接口,而且随一个
Observable对象进行了注册。若点击一个箱子,其他所有箱子都会收到一个通知,指出一个改变已经发生。
这是由于Observable 对象会自动调用每个Observer 对象的 update()方法。在这个方法内,箱子会检查被点
中的那个箱子是否与自己紧邻。若答案是肯定的,那么也修改自己的颜色,保持与点中那个箱子的协调。 个人理解:一个对象改变了,通知所有已经关联的对象,并做相关的处理。
---待续
《Java编程思想第四版》第 16 章 设计范式-提到观察者模式的更多相关文章
- java编程思想第四版第十一章习题
第一题 package net.mindview.holding.test1; import java.util.ArrayList; import java.util.List; /** * 沙鼠 ...
- Java编程思想第四版*第七章*个人练习
欢迎加群:239063848 成团的笔记:该组仅用于技术共享和交流,问题和答案公布 潘基聊天.禁止广告.禁止招聘-- 练习1:(2)创建一个简单的类.第二个类中,将一个引用定义为第一个类的对象.运用惰 ...
- java编程思想第四版第六章习题
(略) (略) 创建两个包:debug和debugoff,他们都包含一个相同的类,该类有一个debug()方法,第一个版本显示发送给控制台的String参数,而第二版本什么也不做,使用静态import ...
- java编程思想第四版第十三章字符串 习题
fas 第二题 package net.mindview.strings; import java.util.ArrayList; import java.util.List; /** * 无限循环 ...
- java编程思想第四版第七章习题
(略) (略) (略) (略) 创建两个带有默认构造器(空参数列表)的类A和类B.从A中继承产生一个名为C的新,并在C内创建一个B类的成员.不要给C编写构造器.创建一个C类的对象并观察其结果. pac ...
- java编程思想第四版第六章总结
1. 代码重构 为什么f要代码重构 第一次代码不一定是完美的, 总会发现更优雅的写法. 代码重构需要考虑的问题 类库的修改不会破坏客户端程序员的代码. 源程序方便扩展和优化 2. 包 创建一个独一无二 ...
- java编程思想第四版第五章习题
创建一个类, 它包含一个未初始化的String引用.验证该引用被Java初始化成了null package net.mindview.initialization; public class Test ...
- java编程思想 第四版 第六章 个人练习
欢迎加群:239063848 进群须知:本群仅用于技术分享与交流.问题公布与解答 禁止闲聊.非诚勿扰 练习1:(1)在某个包中创建一个类,在这个类所处的包的外部创建该类的一个实例. import mi ...
- Java编程思想第四版 *第五章 个人练习
练习3:(1)创建一个带默认构造器(即无參构造器)的类.在构造器中打印一条消息.为这个类创建一个对象.P116 public class Test{ public Test(){ System.out ...
随机推荐
- https进行配置以及http跳转到https配置
https配置: nginx配置 server { listen 443; server_name localhost; ssl on; root html; index index.html ind ...
- iis .apk .ipa下载设置
.apk .ipa无法下载 解决步骤:1).打开IIS服务管理器,找到服务器,右键-属性,打开IIS服务属性:2.单击MIME类型下的“MIME类型”按钮,打开MIME类型设置窗口:3).单击“新建” ...
- 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!
想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了! 很多通信系统发展到某种程度都会有小型化的趋势.一方面小型化可以让系统更加轻便和有效,另一方面,日益发展的IC**技术可以用更低的成本生产 ...
- xml转对象,对象转xml工具类
package com.dq.schooldomain.utils; import com.thoughtworks.xstream.XStream; import com.thoughtworks. ...
- maven eclipse web 项目 问题 cannot change version of project facet dynamic web module to 3.0
cannot change version of project facet dynamic web module to 3.0 修改 web.xml 头部 xsi:schemaLocation=&q ...
- 自己动手,打造轻量级VSCode/C#环境代替LinqPad
.Net 的项目都挺重的,一直想找一个轻量级的 CSharp 环境,能像Python那样,选一个文件就能跑的.之前用的是 LinqPad,但它的缺点也很明显: (1) 不付费,自动完成不能用( ...
- vue数组变异方法
Vue数组变异方法,会改变被这些方法调用的原始数组,将会触发视图更新 push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度 pop() 从数组末尾移除最后一项,减少数组的 ...
- Monkey简介
Monkey简介 在Android的官方自动化测试领域有一只非常著名的“猴子”叫Monkey,这只“猴子”一旦启动,就会让被测的Android应用程序像猴子一样活蹦乱跳,到处乱跑.人们常用这只“猴子” ...
- Win10图片打不开文件系统错误2147416359解决方法
该问题表现为win10打开所有图片都会提示这个‘文件系统错误-2147416359’,打开其他文件没问题.此问题应该是win10自带的图片查看器出了故障. 在网上找到如下方案,但是我的服务列表里没有这 ...
- LODOP中的纯文本和超文本打印项
LODOP中的的打印项,有超文本也有纯文本,超文本指的是用html语言,html里的标签为值的打印项,该种打印项会经过浏览器解析,LODOP本身不带解析超文本的引擎,调用的windows底层引擎,与i ...