将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作.
比如我们日常开发中使用到的slf4j就使用了适配器模式,slf4j提供了一系列打日志的api,底层调用的是log4j或者logback来打日志,而作为调用者,不需要关心底层具体使用的是哪种库,只需要调用slf4j的api就行了。
适配器模式(Adapter)包含以下主要角色。
目标(Target)接口:可以是抽象类或接口。客户希望直接用的接口
适配者(Adaptee)类:隐藏的转换接口
适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口
如下图所示,目标就是实际干活的类,如log4j,logback,适配者就是slf4j,适配器就是slf4j-log412.jar,把可以把log4j的接口转成slf4j的接口
下面我们来模拟slf4j的实现过程,这是slf4j的api,我们的系统中都是通过这个api来打日志的,就像我们生活中用到的电器都是220v的
public interface Slf4jApi {
// 打日志
void log(String log);
}
这是log4j的api,与我们使用的日志api不兼容,就像我们去日本旅游,他们的电压是110V的,我们带过去的电器都没法使用
public class Log4j {
void log4jLog(String log) {
System.out.println(log);
}
}
这时我们就需要一个适配器来适配了
public class Slf4jLog4jAdapter implements Slf4jApi {
private Log4j log4j;
public Slf4jLog4jAdapter(Log4j log4j) {
this.log4j = log4j;
}
@Override
public void log(String log) {
log4j.log4jLog(log);
}
}
测试代码
public class MainTest {
public static void main(String[] args) {
Log4j log4j = new Log4j();
Slf4jApi slf4jApi = new Slf4jLog4jAdapter(log4j);
slf4jApi.log("这是日志");
}
}
可以看到,我们不需要改变我们所使用的日志api,只要通过适配器转换下,就能保证老系统的平稳运行。