别称
包装器适配器
目的
将接口转换成客户希望的另一个接口。适配器能让接口不兼容的类工作在一起。
译者补充: 适配器模式在详细设计阶段不需要考虑它,它是为了对现有系统或产品接口兼容时,也就是既成事实的情况下的补救措施。
解释
生活上的案例
假设你需要将SD卡上的照片传到电脑里,但你的电脑不能直接连接SD卡。这时候,你需要一个读卡器,SD卡插在读卡器,读卡器通过USB插到电脑,这样,你就可以将照片传到电脑了。这里,读卡器就是一种适配器。电源转换器是另一个适配器案例,比如 香港买的电子产品是 三正脚,而大陆仅支持三斜脚,为连接电源就需要电源转换器了。还有一个案例: 翻译者将一种语言转换成另一种语言表达。
白话
适配器模式就是将不兼容的对象通过适配器封装,使得其跟其他对象兼容
维基百科
在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作,做法是将类自己的接口包裹在一个已存在的类中。
编程实例
假设有这样一个船长,只会皮筏艇,不会用帆船/渔船。
这里我们定义接口'RowingBoat'和'FishingBoat'
public interface RowingBoat {
void row();
}
public class FishingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
public void sail() {
LOGGER.info("The fishing boat is sailing");
}
}
船长实现了RowingBoat
interface
public class Captain implements RowingBoat {
private RowingBoat rowingBoat;
public Captain(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
}
@Override
public void row() {
rowingBoat.row();
}
}
这时候海盗来了,我们的船长需要逃跑,但现在只有一艘渔船。我们需要创建一个适配器,让船长可以操作渔船
public class FishingBoatAdapter implements RowingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
private FishingBoat boat;
public FishingBoatAdapter() {
boat = new FishingBoat();
}
@Override
public void row() {
boat.sail();
}
}
现在,我们的船长可以使用渔船逃跑了
Captain captain = new Captain(new FishingBoatAdapter());
captain.row();
适用的场景
遇到以下场景,考虑使用适配器模式:
- 你想使用现有的一个类,但其接口不匹配你使用的
- 你想创建一个可以复用的类,需要和不相干的或者不可预见的类,就是,没有统一兼容接口的类
- 你想使用好几个已存在的子类,通过继承每个子类的方式来适配是不切实际的。对象适配器能够调整其父类的接口
- 当系统使用很多第三方组件,通过适配器作为该应用和第三方组件的中间层,可以做到解耦。如果新增一个第三方,只要新增一个对应的适配器就可以使用,而不需要修改系统
两种适配器
类适配器和对象适配器之前的差异。
类适配器: 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。
- 类适配器将具体的类作为被适配者,这样导致需要适配所有子类时 就不能用了
- 因为是子类,所以可以修改被适配者的行为
- 只有一个实例,无法引用到被适配者
![](https://img.haomeiwen.com/i13299050/1e3862e5919a0d15.jpg)
对象适配器: 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
- 一个对象适配器,可以用于多个被适配者--所有子类,还可以给所有子类添加新的功能方法
- 很难修改被适配者的行为
![](https://img.haomeiwen.com/i13299050/702b810b9ae4de25.jpg)
网友评论