设计模式之适配器模式笔记
- 说明
- Adapter(适配器)
- 目录
- 类适配器模式示例类图
- 适配者类的接口
- 适配者类
- 目标接口
- 具体的SD卡类
- 计算机类
- 适配器类
- 测试类
- 对象适配器模式
- 适配者类的接口
- 适配者类
- 目标接口
- 具体的SD卡类
- 计算机类
- 适配器类
- 测试类
说明
记录下学习设计模式-适配器模式的写法。JDK使用版本为1.8版本。
Adapter(适配器)
意图:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
结构:
其中:
- Target定义Client使用的与特定领域相关的接口。
- Client与符合Target接口的对象协同。
- Adaptee定义一个已经存在的接口,这个接口需要适配。
- Adapter对Adaptee的接口与Target接口进行适配。
适用性:
- 想使用一个已经存在的类,而它的接口不符合要求。
- 想创建一个可以服用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
- (仅适用于对象Adapter)想使用一个已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
应用场景:
1.以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
2.使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。
目录
类适配器模式示例类图
现有一台电脑只能读取SD卡,而要读取TF卡中的内容的话就需要使用到适配器模式。创建一个读卡器,将TF卡中的内容读取出来。类图如下:
以该UML类图实现类适配器模式示例。
适配者类的接口
package com.example.deesign_patterns.adapter.class_adapter;
//适配者类的接口
public interface TFCard {
//从TF卡中读取数据
String readTF();
//往TF卡中写数据
void writeTF(String msg);
}
适配者类
package com.example.deesign_patterns.adapter.class_adapter;
//适配者类
public class TFCardImpl implements TFCard{
@Override
public String readTF() {
String msg="TFCard read msg:hello world";
return msg;
}
@Override
public void writeTF(String msg) {
System.out.println("TFCard write msg:"+msg);
}
}
目标接口
package com.example.deesign_patterns.adapter.class_adapter;
//目标接口
public interface SDCard {
//从SD卡中读取数据
String readSD();
//往SD卡中写数据
void writeSD(String msg);
}
具体的SD卡类
package com.example.deesign_patterns.adapter.class_adapter;
//具体的SD卡类
public class SDCardImpl implements SDCard{
@Override
public String readSD() {
String msg="SDCard read msg:hello world";
return msg;
}
@Override
public void writeSD(String msg) {
System.out.println("SDCard write msg:"+msg);
}
}
计算机类
package com.example.deesign_patterns.adapter.class_adapter;
//计算机类
public class Computer {
//从SD卡中读取数据
public String readSD(SDCard sdCard){
if(sdCard==null){
throw new NullPointerException("sd card is not null");
}
return sdCard.readSD();
}
}
适配器类
package com.example.deesign_patterns.adapter.class_adapter;
//适配器类
public class SDAdapterTF extends TFCardImpl implements SDCard{
@Override
public String readSD() {
System.out.println("adapter read tf card");
return readTF();
}
@Override
public void writeSD(String msg) {
System.out.println("adapter write tf card");
writeTF(msg);
}
}
测试类
package com.example.deesign_patterns.adapter.class_adapter;
//测试类
public class Client {
public static void main(String[] args) {
//创建计算机对象
Computer computer=new Computer();
//读取SD卡中的数据
String msg=computer.readSD(new SDCardImpl());
System.out.println(msg);
System.out.println("========================");
//使用该电脑读取TF卡中的数据
//定义适配器类
String msg1=computer.readSD(new SDAdapterTF());
System.out.println(msg1);
}
}
类适配器模式违背了合成复用原则。类适配器是客户类有一个接口规范的情况下可用,反之不可用。
对象适配器模式
对上面案例进行改写,类图如下:
适配者类的接口
package com.example.deesign_patterns.adapter.object_adapter;
//适配者类的接口
public interface TFCard {
//从TF卡中读取数据
String readTF();
//往TF卡中写数据
void writeTF(String msg);
}
适配者类
package com.example.deesign_patterns.adapter.object_adapter;
//适配者类
public class TFCardImpl implements TFCard {
@Override
public String readTF() {
String msg="TFCard read msg:hello world";
return msg;
}
@Override
public void writeTF(String msg) {
System.out.println("TFCard write msg:"+msg);
}
}
目标接口
package com.example.deesign_patterns.adapter.object_adapter;
//目标接口
public interface SDCard {
//从SD卡中读取数据
String readSD();
//往SD卡中写数据
void writeSD(String msg);
}
具体的SD卡类
package com.example.deesign_patterns.adapter.object_adapter;
//具体的SD卡类
public class SDCardImpl implements SDCard {
@Override
public String readSD() {
String msg="SDCard read msg:hello world";
return msg;
}
@Override
public void writeSD(String msg) {
System.out.println("SDCard write msg:"+msg);
}
}
计算机类
package com.example.deesign_patterns.adapter.object_adapter;
//计算机类
public class Computer {
//从SD卡中读取数据
public String readSD(SDCard sdCard){
if(sdCard==null){
throw new NullPointerException("sd card is not null");
}
return sdCard.readSD();
}
}
适配器类
package com.example.deesign_patterns.adapter.object_adapter;
//适配器类
public class SDAdapterTF implements SDCard {
//声明适配者类,聚合对象
private TFCard tfCard;
//创建一个有参构造方法
public SDAdapterTF(TFCard tfCard) {
this.tfCard = tfCard;
}
@Override
public String readSD() {
System.out.println("adapter read tf card");
return tfCard.readTF();
}
@Override
public void writeSD(String msg) {
System.out.println("adapter write tf card");
tfCard.writeTF(msg);
}
}
测试类
package com.example.deesign_patterns.adapter.object_adapter;
//测试类
public class Client {
public static void main(String[] args) {
//创建计算机对象
Computer computer=new Computer();
//读取SD卡中的数据
String msg=computer.readSD(new SDCardImpl());
System.out.println(msg);
System.out.println("========================");
//使用该电脑读取TF卡中的数据
//创建适配器类对象
SDAdapterTF sdAdapterTF = new SDAdapterTF(new TFCardImpl());
String msg1=computer.readSD(sdAdapterTF);
System.out.println(msg1);
}
}
注意:还有一个适配器模式是接口适配器模式。当不希望实现一个接口中所有方法时,可以创建一个抽象类Adapter,实现所有方法。而此时我们只需要继承该抽象类接口。
JDK源码中Reader(字符流)、InputStream(字节流)的适配使用的是InputStreamReader。
结论:从表层来看,InputStreamReader做了InputStream字节流类到Reader字符流之间的转换。而从如上实现类关系结构中可以看出,是StreamDecoder的设计实现在实际上采用了适配器模式。