适配器模式:将一个类的接口转换成客户端所期望的另一个接口,从而使得原本不兼容的类能够一起工作。它属于结构型模式,可以帮助我们解决接口不匹配的问题。

适配器模式的目标是在不修改现有类的情况下,使得不兼容的类能够适应系统的需求。通过引入适配器,客户端可以通过统一的接口与不同的类进行交互,而不需要了解这些类的具体实现细节。

用图表示如下:

适配器模式的优点:

  • 代码重用:适配器模式可以重用现有的类,而无需修改其代码。通过适配器,可以将不兼容的类集成到现有系统中,提高代码的可重用性和灵活性。

  • 系统扩展性:适配器模式使得系统更加灵活,可以方便地添加新的适配器类来适配新的类或接口。这样,在系统需要支持新的类或接口时,可以通过添加适配器来实现,而不需要修改现有的代码。

  • 解耦合:适配器模式将目标类和适配者类解耦,它们可以独立演化。适配器模式使得目标类和适配者类之间的依赖关系减少,提高了系统的灵活性和可维护性。

  • 兼容性:适配器模式可以解决不同接口之间的兼容性问题。通过适配器,可以将不兼容的接口转换为客户端所期望的接口,使得原本无法协同工作的类能够一起工作。

适配器模式的的缺点:

  • 增加了复杂性:引入适配器模式会增加代码的复杂性,因为需要添加额外的适配器类。如果系统中有大量的适配器类,会增加代码的阅读和维护的难度。

  • 运行时性能损失:适配器模式在运行时需要进行额外的适配操作,可能会引入一定的性能损失。尤其是在处理大量数据时,适配器模式的性能影响可能会比较明显。

  • 过度使用的风险:适配器模式可能会被滥用,导致系统中出现过多的适配器类。如果不加限制地使用适配器模式,可能会导致系统结构变得复杂而难以理解。

适配器模式的主要角色如下:

  1. 目标接口(Target Interface):这是客户端所期望的接口。适配器将源接口转换为目标接口,以便客户端能够使用。

  2. 源接口(Adaptee Interface):这是需要被适配的接口。它是不兼容于目标接口的。

  3. 适配器(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());
   }

}  
文章作者: Hakurei
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Zero
设计模式 设计模式 Java
喜欢就支持一下吧