适配器模式
适配器模式:将一个类的接口转换成客户端所期望的另一个接口,从而使得原本不兼容的类能够一起工作。它属于结构型模式,可以帮助我们解决接口不匹配的问题。
适配器模式的目标是在不修改现有类的情况下,使得不兼容的类能够适应系统的需求。通过引入适配器,客户端可以通过统一的接口与不同的类进行交互,而不需要了解这些类的具体实现细节。
用图表示如下:

适配器模式的优点:
代码重用:适配器模式可以重用现有的类,而无需修改其代码。通过适配器,可以将不兼容的类集成到现有系统中,提高代码的可重用性和灵活性。
系统扩展性:适配器模式使得系统更加灵活,可以方便地添加新的适配器类来适配新的类或接口。这样,在系统需要支持新的类或接口时,可以通过添加适配器来实现,而不需要修改现有的代码。
解耦合:适配器模式将目标类和适配者类解耦,它们可以独立演化。适配器模式使得目标类和适配者类之间的依赖关系减少,提高了系统的灵活性和可维护性。
兼容性:适配器模式可以解决不同接口之间的兼容性问题。通过适配器,可以将不兼容的接口转换为客户端所期望的接口,使得原本无法协同工作的类能够一起工作。
适配器模式的的缺点:
增加了复杂性:引入适配器模式会增加代码的复杂性,因为需要添加额外的适配器类。如果系统中有大量的适配器类,会增加代码的阅读和维护的难度。
运行时性能损失:适配器模式在运行时需要进行额外的适配操作,可能会引入一定的性能损失。尤其是在处理大量数据时,适配器模式的性能影响可能会比较明显。
过度使用的风险:适配器模式可能会被滥用,导致系统中出现过多的适配器类。如果不加限制地使用适配器模式,可能会导致系统结构变得复杂而难以理解。
适配器模式的主要角色如下:
目标接口(Target Interface):这是客户端所期望的接口。适配器将源接口转换为目标接口,以便客户端能够使用。
源接口(Adaptee Interface):这是需要被适配的接口。它是不兼容于目标接口的。
适配器(Adapter):适配器是一个类,它实现了目标接口,并且包含一个对源接口的引用。适配器将客户端的请求转发给源接口,并根据需要进行适当的转换。
适配器模式的实现
1.类适配器模式

// 目标接口
interface Target {
public void request();
}
// 适配者接口
class Adaptee {
public void specificRequest() {
System.out.println("适配者中的业务代码被调用!");
}
}
// 类适配器类
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest();
}
}
// 测试类
public class ClassAdapterTest {
public static void main(String[] args) {
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}程序的运行结果如下:
类适配器模式测试:
适配者中的业务代码被调用!2.对象适配器模式

//对象适配器类
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
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();
}
}程序的运行结果如下:
对象适配器模式测试:
适配者中的业务代码被调用!适配器模式总结:
适配器模式是一种重要的设计模式,通过适配器将不兼容的接口转换为客户端所期望的接口,以解决接口不兼容的问题,提高代码的可重用性和灵活性。
适配器模式在Spring框架中的应用
在Spring的Aop中,使用Advice(通知)来增强被代理类的功能,Advice的常用类型有:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice。每种Advice都有对应的拦截器,分别为MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。各种不同类型的Interceptor,通过适配器统一对外提供接口,最终调用不同的advice来实现被代理类的增强。
package org.springframework.aop.framework.autoproxy;
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
……
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
} 使用适配器模式,将MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice这三个通知类适配成Advisor
package org.springframework.aop.framework.adapter;
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
// 在调用被cglib动态的对象时,会调用InterceptionAdvice链拦截目标方法
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
}
// 三种适配器
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof AfterReturningAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdvice advice = (AfterReturningAdvice) advisor
.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}
}
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof ThrowsAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}
}