适配器模式
在面向对象的程序设计中,我们经常会反复地遇到相同的问题,于是有人就做了抽象,把这些可能反复出现的场景提取出来,用一种通用的方法去解决它。我们把这种通用的方法叫做设计模式。
例如,我们第一篇文章里的问题。需求是直接处理字符,但是,输入进来的却是编码的字节。我们希望有这么一个类,能自动解码并向我们提供字符读写的接口。这个类打通了字节处理与字符处理之间的堑沟。这个类就叫做适配器类。下面是它的类图
通过这个图,可以看到,我们期望的接口是Target类型的,这个类型定义了request这个方法。但是我们只有一个Adaptee的对象,它只能提供specificRequest,所以我们就自己做了一个适配器类Adaptor,这个类中有一个成员变量是Adaptee类型的。使用Adaptee提供的方法实现Target接口,这就是适配器做的事情。
回到我们的具体问题,现在已经有了字节码处理的 InputStream,我们的目标接口是可以处理字符的Reader,所以我们就需要一个可以把字节码转成字符的 InputStreamReader。这就是适配器的能力啊。
public static void main(String args[]) {
char[] cbuf = new char[256];
System.out.println("hey, may I have your name, please? ");
int n = 0;
Reader r = new InputStreamReader(System.in);
try {
n = r.read(cbuf);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("hello, Mr. " + cbuf[0]);
}
可以看到,我们终于可以通过 char 类型的数组直接拿到解码好的汉字了。这个程序里,字节InputStream 到字符 Reader 的适配器类 InputStreamReader 居功至伟。
我们把适配器类的分析拿过来,分析一下 java io 这个 package 里的类都是些什么。
已经有了操作文件的 File,我们的目标接口是可以处理字节的 InputStream,所以我们就需要一个可以把文件操作变成流操作的 FileInputStream。
已经有了操作网络接口的 Socket,我们的目标接口是可以处理字节的 InputStream,所以我们就需要一个可以把网络操作变成流操作的 SocketInputStream。
已经有了操作字符串的String,我们的目标接口是可以处理字符的 Reader,所以我们就需要一个可以把字符串操作变成字符操作的 StringReader。
…………
这个可以写很长。如果有读者曾经读过的我一个关于如何学习Java的文章,应该还记得,我曾经说过,IO的类是不用去死记硬背的,学完了几个常见的设计模式,有些类名,自己猜都能猜出来。呐,这就是我的课程里介绍的第一个设计模式:适配器模式。是不是感觉到 java.io http:/ja这个package瞬间就毫无秘密可言了呢?
记住 InputStreamReader / OutputStreamWriter 是连通字节与字符的桥梁。XxxReader(InputStream / OutputStream / Writer) 则是连通某一类操作与输入输出流的桥梁。那么 java.io http://java就掌握了大部分了。
- go sync.Mutex 设计思想与演化过程 --转
- 漏洞预警 | Ubuntu 16.04版本存在本地提权漏洞(附EXP)
- 通过“震网三代”和Siemens PLC 0day漏洞,实现对工控系统的入侵实验
- 安卓端渗透工具DVHMA:自带漏洞的混合模式APP
- 小萝莉说Crash(二): Unrecognized selector xxx 之 ForwardInvocation
- 5分钟教程:如何通过UART获得root权限
- 源码级剖析PHP 7.2.x GD拒绝服务漏洞
- 美女程序媛发福利,读懂ANR的trace文件So easy
- Openshift高阶探索实验
- 卡卡卡!小萝莉告诉你开发iOS应用如何避免卡顿
- Bugly即将支持的ANR,精神哥告诉你是个什么鬼?
- Go语言Goroutine与Channel内存模型
- 手把手教 | 深度学习库PyTorch(附代码)
- 如何定位Obj-C野指针随机Crash(一):先提高野指针Crash率
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法