本文介绍23种设计模式之适配器模式。
定义
将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。 适配器分为 类适配器和对象适配器,类适配器通过集成的方式,对象适配器通过组合的方式。java没有多继承,因此是无法做到类适配器的。
描述
- 模式名称:ADAPTER(适配器)
- 类型:类/对象创建型模式
- 意图:将一个类的接口转换成客户希望的另外一个接口。 适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 适用性:
- 想使用一个已经存在的类,而它的接口不符合你的需求。
- 想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
- 想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
- 效果:
- 优点:
- 可以让任何两个没有关联的类一起运行。
- 提高复用性。
- 客户端通过适配器可以透明地调用目标接口。
- 缺点:
- 过多的使用适配器,会让系统非常零乱,增加代码阅读难度,降低代码可读性,不易维护。
类图
类适配器
通过继承适配目标和适配者的方式来实现转换的。
对象适配器
通过组合的方式实现适配。
- 目标(Target)接口:定义Client使用的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:定义一个已经存在的接口,这个接口需要适配。
- 适配器(Adapter)类:对Adaptee的接口与Target接口进行适配。
实现代码
如何将Enumeration变为Iterator。
类图
在java早期的集合类中:vector,stack,Hashtable 都有实现elements()方法 返回 Enumeration对象
Enumeration(Adaptee)
public interface Enumeration<E> {
/**
* 返回是否还有更多的元素
*/
boolean hasMoreElements();
/**
* 返回下一个元素
*/
E nextElement();
}
后面推出了新的迭代器 Iterator (Target)
public interface Iterator<E> {
/**
* 返回是否还有更多的元素
*/
boolean hasNext();
/**
* 返回迭代中的下一个元素。
*
*/
E next();
/**
* 从集合中移除返回的最后一个元素
*
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
Adapter
Iterator的remove()方法使用default修饰,可以不用实现
//通过传入的enumeration对象的方法转换为Iterator的方法
public class EnumerationAdapter implements Iterator {
private Enumeration enumeration;
public EnumerationAdapter(Enumeration enumeration) {
this.enumeration = enumeration;
}
@Override
public boolean hasNext() {
return enumeration.hasMoreElements();
}
@Override
public Object next() {
return enumeration.nextElement();
}
}