《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 ...
随机推荐
- day14- 面向对象基础(一)
今天开始写关于面向对象的内容,面向对象是编程思想中一大思想,由于日常使用中经常会用到,本次主要是对于我个人认为重点的基础知识进行整理,不会特别详细的书写. 1.面向过程与面向对象的区别 2.类 3.类 ...
- Oracle 查询重复索引列
SELECT /*+ rule */ a .table_owner, a.table_name, a.index_owner, a.index_name, column_name_list, colu ...
- springMVC第二天——高级参数绑定与其它特性
大纲摘要: 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 2.@RequestMapping注解的使用 3.Controller方法返回值 4.Springmvc中异常处理 5 ...
- TortoiseGit 安装
1.TortoiseGit 下载安装 2.语言包下载安装 3.配置语言 一 TortoiseGit 下载安装 官网下载地址:https://download.tortoisegit.org/tgit/ ...
- 【Topcoder 1643】PossibleOrders
题意:给一些等价关系,问把所有的数按照大小排序的种类数. 思路:首先并查集维护等价类,然后设有\(n\)个等价类. 那么就可以\(dp\)了. 考虑\(dp(i)\)表示还剩下\(i\)个等价类,答案 ...
- 使用Mycat构建MySQL读写分离、主从复制、主从高可用
数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能. 从数据库的角度来说,对于大多数应用来说,从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于计算的瓶颈,即S ...
- 偶现bug如何处理?
请先允许我对此类bug进行吐槽,相信做测试的同学都碰见过这种bug! 我们在测试过程中经常会碰见一类很头疼的bug,就是偶现性的bug,所谓偶现性,是相对于必现而言,这类bug有些可以有重现路径,但是 ...
- Golang 入门系列(一)Go环境搭建
安装 Go Go语言的优劣,这里就不介绍了,下面直接讲Go 的安装: Go 的官方网站:http://golang.org/(需要FQ软件) 国内下载地址:http://www.golangtc.co ...
- vue style标签中使用less
只需要下载相应的包即可:(前提是使用vue-cli搭建的项目) 1.安装less依赖,npm install less less-loader --save 2.即可在相应的vue文件中使用less操 ...
- openstack第四章:neutron— 网络服务
第四篇neutron— 网络服务 一.neutron 介绍: Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是 ...