前言 : 个人理解, 适配的意思即为, 把一个东西适当的改变一哈, 变为可以配合另一个东西使用的能力, 适配器就是拥有这种能力的东西.
在 java 设计模式中, 适配器的意思也是相同的, 即把一个接口适配成另一种接口的样子, 这里所说的接口, 必须是拥有大体相同的功能, 或者是一个功能的不同实现, 否则适配的目的就显得非常不单纯了或者说根本无法适配.
适配器模式
JDK 曾经的某个版本中有对集合元素的处理接口 Enumeration, 如下 :
public interface Enumeration {
boolean hasMoreElement();
Object getNext();
}
假如有一个具体实现 :
public class ConcreteEnumeration implements Enumeration {
@Override
public boolean hasMoreElement() {
System.out.println("this is method hasMoreElement from Enumeration . ");
return true;
}
@Override
public Object getNext() {
System.out.println("this is method getNext from Enumeration . ");
return null;
}
}
一个旧有服务中暴露出此接口 :
public class OldService {
public static Enumeration getEnumerator() {
return new ConcreteEnumeration();
}
}
后期 JDK 提供了新的集合服务接口 Iterator :
public interface Iterator {
boolean more();
Object next();
void remove();
}
一个具体实现 :
public class ConcreteIterator implements Iterator {
@Override
public boolean more() {
System.out.println("this is method more from Iterator . ");
return false;
}
@Override
public Object next() {
System.out.println("this is method next from Iterator . ");
return null;
}
@Override
public void remove() {
System.out.println("this is method remove from Iterator . ");
}
}
新的服务中开始使用新接口 :
public class NewService {
public static void processIterator(Iterator iterator) {
// TODO
}
}
那么问题来了, 旧有服务还需要使用, 那么旧有服务暴露出来的旧有接口我们还需要兼容使用, 如何处理 ?
public class Client {
public static void main(String[] args) {
// 编译出错, 不兼容旧接口, 不能使用旧服务
NewService.processIterator(OldService.getEnumerator());
}
}
于是适配器出现了, 来看看它是如何工作的 :
public class Adapter implements Iterator {
private Enumeration enumeration;
public Adapter(Enumeration enumeration) {
this.enumeration = enumeration;
}
@Override
public boolean more() {
return enumeration.hasMoreElement();
}
@Override
public Object next() {
return enumeration.getNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
分析 :
1.它实现了需要适配成的接口(Iterator)
2.它保有一个被适配的接口(Enumeration)
3.它实现要适配成的接口的方法
4.3中实现的方法里时机调用的是被适配接口的方法
5.如果有新接口提供但是旧接口没提供的方法, 可以抛出一个不支持的操作的异常.
这样旧接口便被兼容到了新接口上.
来看看客户端如何调用 :
public class Client {
public static void main(String[] args) {
NewService.processIterator(new Adapter(OldService.getEnumerator()));
}
}
如此简单.
适配器模式的作用 :
- 系统需要使用现有的类,而这些类的接口不符合系统的接口
- 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作
- 两个类所做的事情相同或相似,但是具有不同接口的时候
- 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候
- 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能