如果想让额定工作电压是直流 12 伏特的笔记本电脑在交流 220 伏特的 AC(Alternating Current) 电源下工作,应该怎么做呢?通常,我们会使用 AC 适配器,将家庭用的交流 220 伏特电压转换成我们所需要的直流 12 伏特电压。这就是适配器的工作,它位于实际情况与需求之间,填补两者之间的差异。
接口适配器
电源适配器
适配器的角色
在程序世界中,经常会存在现有的程序无法直接使用,需要做适当的变换之后才能使用的情况。这种用于填补『现有的程序』和『所需的程序』之间差异的设计模式就是 Adapter 模式。在 Java 中,adapter 模式有如下两种实现。
- 使用继承的适配器
- 使用委托的适配器
示例程序
电源的比喻与示例程序的关系
电源的比喻 | 示例程序 | |
---|---|---|
实际情况 | 交流 220 伏特 | AlternateCurrent 类(use220V) |
转换装置 | 适配器 | AlternateToDirect 类 |
需求 | 直流 12 伏特 | DirectCurrent 类(use12V) |
实际情况
不管是继承适配器还是委托适配器,实际情况都是不变的。
1 | public class AlternateCurrent { |
Main 类
1 | public class Main { |
继承适配器
需求是一个接口。
需求
1 | public interface DirectCurrent { |
转换装置
1 | public class AlternateToDirect extends AlternateCurrent implements DirectCurrent { |
类图
继承适配器
委托适配器
需求是一个类。
需求
1 | public abstract class DirectCurrent { |
转换装置
1 | public class AlternateToDirect extends DirectCurrent { |
类图
委托适配器
总结
Adapter 模式用于填补具有不同 API 的两个类之间的缝隙。
什么时候用 Adapter 模式
如果某个方法就是我们所需要的方法,那么直接在程序中使用不就可以了吗,为什么还要考虑使用 Adapter 模式呢?那么,究竟应当在什么时候使用 Adapter 模式呢?
- 很多时候,我们并非从零开始编程,经常会用到现有的类。
- 特别是当现有的类已经被充分测试过了,Bug 很少,而且已经被用于其他软件之中时,我们更愿意将这些类作为组件重复利用。
- 版本升级与兼容性。
- 软件的生命周期总是伴随着版本的升级,而在版本升级的时候经常会出现『与旧版本的兼容性问题』。如果能够完全抛弃旧版本,那么软件的维护工作将会轻松得多,但是现实中往往无法这样做。这时,可以使用 Adapter 模式使新旧版本兼容,帮助我们轻松地同时维护新版本和旧版本。
功能完全不同的类
当然,当『需求』角色和『实际情况』角色的功能完全不同时,Adapter 模式是无法使用的。就如同我们无法用交流 220 伏特电压让自来水管出水一样。
拓展
习题
在 java.util.Properties 类中,可以像下面这样管理键值对(属性)。
1 | year=2018 |
java.util.Properties 类提供了以下方法,可以帮助我们方便地从流中取出属性或写入。
1 | //从 InputStream 中取出属性集合。 |
请使用 Adapter 模式编写一个将属性集合保存至文件的 FileProperties 类。
这里,我们假设在下面代码中的 FileIO 接口中声明了将属性集合保存至文件的方法,并假设 FileProperties 类会实现这个 FileIO 接口。
FileIO
1 | public interface FileIO { |
Main
1 | /** |
输入文件(adapter.txt)
1 | year=1999 |
输出文件(newAdapter.txt)
1 | #written by FileProperties |