Adapter Pattern的作用是在不改变功能的前提下转换接口。Adapter分为两类,一类是Object Adapter, 还有一类是Class Adapter。因为Class Adapter的实现须要用到多继承,而Java不支持多继承,所以这里仅仅关注Object Adapter。

在JDK1.5之前是没有 java.util.Iterator 接口的,java.util.Enumeration 接口起着 Iterator 的作用。那么假设我们须要维护一些年代比較久远的代码,可能就会面临着没有 Iterator 的窘境。这时候 Adapter Pattern 就派上用场了。以下通过两个样例,说明怎样通过 Adapter Pattern 将 Enumeration 接口与 Iterator 接口相互“转换”。

老代码适配新代码:将Enumeration转换为Iterator

查了一下API文档,发现 StringTokenizer 这个类实现了 Enumeration 接口,那就拿这个来举例吧。如今有需求,须要用 Iterator 的方式来"遍历" StringTokenizer,可是 StringTokenizer类并没有实现 Iterator 接口。因此我们须要编写一个 Adapter,将 Enumeration 接口转换成 Iterator 接口。



class IteratorAdapter implements Iterator {
private Enumeration enume; // 保存 Enumeration 接口实现类 public IteratorAdapter(Enumeration enume) {
this.enume = enume;
} /**
* Enumeartion的hasMoreElements()方法与Iterator的hasNext()方法功能同样,直接调用
*/
@Override
public boolean hasNext() {
return enume.hasMoreElements();
} /**
* Enumeration的next()方法与Iterator的next()方法功能同样,直接调用
*/
@Override
public Object next() {
return enume.nextElement();
} /**
* 因为Enumeration接口中没有此方法,所以扔异常
*/
@Override
public void remove() {
throw new UnsupportedOperationException(); } }

能够看到,我们实际上仅仅是把没有实现的 Iterator 接口里的方法实现托付给了 Enumeration 接口的实现。

Adapter 的用法例如以下:
StringTokenizer st = new StringTokenizer("a b c d e f g");

		// 创建adapter对象,将StringTokenizer对象传进去
IteratorAdapter strTokenAdapter = new IteratorAdapter(st); // 这时候就能够用Iterator的方式遍历没有实现Iterator接口的对象了
while(strTokenAdapter.hasNext()) {
out.println(strTokenAdapter.next());
}

新代码适应老代码:将Iterator转换为Enumeration

反过来的过程就非常easy的了,由于 Enumeration 接口里的方法在 Iterator 中都有定义。



class EnumerationAdapter implements Enumeration {
private Iterator it; public EnumerationAdapter(Iterator it) {
this.it = it;
} @Override
public boolean hasMoreElements() {
return it.hasNext();
} @Override
public Object nextElement() {
return it.next();
} }

像上面 IteratorAdapter 和 EnumerationAdapter 那样把要被适配的对象保存到类的成员变量里的方式,就叫 Object Adapter。而还有一种 Class Adapter则是要求 Adapter 类同一时候继承适配的两方。比方,有一个名为Apple的类和名为Banana的类,它们的public方法不同样。如今想以调用Apple类方法的方式使用Banana类,那么对于 Class Adapter 来说,就应该让 Adapter 同一时候继承 Apple 和 Banana,然后通过
Adapter 完毕方法调用。有兴趣的话能够用C++实现一下试试。

最新文章

  1. 一张图看懂git push
  2. php 斐波那契数列
  3. Atitit 控制中心快速启动面板quick launcher
  4. Thinkphp 整理备忘 杂记
  5. php课程---JavaScript改变HTML中的元素
  6. [kuangbin带你飞]专题二十 斜率DP
  7. .NET在EF中使用sql,用动态类吧!
  8. Graham's Scan算法
  9. 352. Data Stream as Disjoint Intervals
  10. mongoDB初接触
  11. jdbcType与javaType的对应关系
  12. WPF实现无窗体鼠标跟随
  13. linux5.8安装oracle10g过程记录,换实例一定要改profile的配置
  14. 横向子菜单栏ul根据其子元素li个数动态获取宽度,并与父li绝对垂直居中的jquery代码段
  15. Hadoop生态圈初识
  16. Java公开课-03.内部类
  17. IdentityServer4【Topic】Consent
  18. P1030 求先序排列 P1305 新二叉树
  19. ionic1 添加百度地图插件 cordova-plugin-baidumaplocation
  20. CynosDB技术详解——存储集群管理

热门文章

  1. NanShan即时通讯论——HTML5的优势与劣势
  2. 在把数据库文件放在raw中,在应用程序中如何打开
  3. Qt学习之路:自定义Model三篇,自定义委托等等
  4. CSS+DIV入门第一天基础视频 CSS选择器层叠性和继承性
  5. Bootstrap技术: 如何给nav导航组件的tab页增加关闭按钮以及动态的添加和关闭tab页
  6. Jquery学习笔记:删除节点的操作
  7. Python 文本解析器
  8. cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理
  9. poj 1182食物链(并查集)
  10. HTML的表单元�