1、什么是适配器模式?
适配器模式就是将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。适配器可分为类适配器和对象适配器。
###2、适配器模式主要涉及3个类型。
- Target:目标抽象类,即客户所需接口,可以是接口,也可以是具体类。
- Adapter:适配器类,适配器模式的核心类,对Adaptee和Target类进行适配。通常通过实现或继承Target类,并关联Adaptee类对象使二者产生联系。
- Adaptee:适配者类,即被适配的角色。
3、适配器的应用实例。
在mybatis中,选择StatementHandler就是采用了适配器模式,具体如下:
public class RoutingStatementHandler implements StatementHandler {
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor,
MappedStatement ms,
Object parameter,
RowBounds rowBounds,
ResultHandler resultHandler,
BoundSql boundSql) {
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
//...
}
上面代码中,RoutingStatementHandler
就是适配器类(adapter),StatementHandler
是目标类(target),而SimpleStatementHandler
、PreparedStatementHandler
、CallableStatementHandler
等则是适配者类(adaptee)。
实际上,上面例子可能还不够太明显,因为StatementHandler
是SimpleStatementHandler
、PreparedStatementHandler
、CallableStatementHandler
等的父类。
接着再看一个例子,ScheduledThreadPoolExecutor
线程池中
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
上述代码中,RunnableAdapter
就是适配器类(adapter),Callable
是目标类(target),Runnable
是适配者类(adaptee),可以看到Callable和Runnable是完全不兼容的两个接口,最终通过RunnableAdapter将Runnable适配成Callable。
4、适配器类型
- 类适配器:在适配器类Adapter中继承适配者类Adaptee并实现目标接口Target,使Adaptee和Target产生联系。
- 对象适配器:在适配器类Adapter中实现目标接口Target,通过关联适配者类Adaptee的对象使Target和Adaptee产生联系。
5、优点
- 可以让两个没有关联的类一起运行。
- 提高了类的复用。
- 增加类的透明度,客户端只关注结果。
- 使用适配器的时候,可以调用自己开发的功能,从而扩展系统的功能。
6、缺点
- 过多使用会导致系统凌乱,追溯困难。