适配器模式
说明
- @author JellyfishMIX - github / blog.jellyfishmix.com
- LICENSE GPL-2.0
简介
适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
自己的理解,使用一个类 A 去实现接口 B,这样可以做到让类 A 兼容接口 B。
适配器模式的代码
类适配器模式
/**
* 目标接口
*/
interface Target {
public void request();
}
/**
* 适配者接口
*/
class Adaptee {
public void specificRequest() {
System.out.println("适配者中的业务代码被调用!");
}
}
/**
* 适配器类
*/
class ClassAdapter extends Adaptee implements Target {
public void request() {
specificRequest();
}
}
/**
* 测试用例
*/
public class ClassAdapterTest {
public static void main(String[] args) {
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}
程序的运行结果如下:
类适配器模式测试:
适配者中的业务代码被调用!
对象适配器模式
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest();
}
}
/**
* 测试用例
*/
public class ObjectAdapterTest {
public static void main(String[] args) {
System.out.println("对象适配器模式测试:");
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request();
}
}
源码中的适配器模式
用于 org.apache.logging.log4j (简称为 lo4j2) 与 slf4j 保持桥接,里面有适配器类。
<!--用于 log4j2 与 slf4j 保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
</dependency>
Log4jMDCAdapter 是 log4j2 用来支持 slf4j 中 MDC 机制(MDC 机制是什么与本文主题无关,可以不用关注)的适配器,使用 log4j2 去实现 slf4j
package org.apache.logging.slf4j;
import java.util.Map;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.spi.MDCAdapter;
/**
* log4j2 用来支持 sl4j 中 MDC 机制的适配器
*/
public class Log4jMDCAdapter implements MDCAdapter {
public Log4jMDCAdapter() {
}
public void put(final String key, final String val) {
ThreadContext.put(key, val);
}
public String get(final String key) {
return ThreadContext.get(key);
}
public void remove(final String key) {
ThreadContext.remove(key);
}
public void clear() {
ThreadContext.clearMap();
}
public Map<String, String> getCopyOfContextMap() {
return ThreadContext.getContext();
}
public void setContextMap(final Map map) {
ThreadContext.clearMap();
ThreadContext.putAll(map);
}
}
可以看到主要有两个 import
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.spi.MDCAdapter;
其中 MDCAdapter 是要实现的目标接口,ThreadContext 是 log4j2 里的一个类也就是适配者(由于 ThreadContext 里是静态方法,适配器并没有去继承它,而是选择直接使用静态方法)。