当前位置 博文首页 > 文章内容

    适配器模式

    作者: 栏目:未分类 时间:2020-07-10 18:09:17

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    1.1模式定义

    将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装(Wrapper)。适配器模式既可以作为类结构型模式(继承关系),也可以作为对象结构型模式(关联关系)。

    1.2角色

    Target:目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
    Adapter:适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
    Adaptee:适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法。

    1.3类结构型

    首先有一个已存在的将被适配的类。具有原本已经存在的接口(类)

    public class Adaptee {
        public void adapteeRequest() {
            System.out.println("被适配者的方法");
        }
    }
    

    定义一个目标接口,(需要通过他的方法调用原来存在的类中的方法)

    public interface Target {
        void request();
    }
    

    我们现在需要在request()方法中调用adapteeRequest()。通过一个适配器类,实现 Target 接口,同时继承了 Adaptee 类,然后在实现的 request() 方法中调用父类的adapteeRequest()

    public class Adapter extends Adaptee implements Target{
        @Override
        public void request() {
            //...一些操作...
            super.adapteeRequest();
            //...一些操作...
        }
    }
    

    这样我们即可在新接口 Target 中适配旧的接口或类

    1.4对象适配器

    对象适配器与类适配器不同之处在于,类适配器通过继承来完成适配,对象适配器则是通过关联来完成,这里稍微修改一下 Adapter 类即可将转变为对象适配器

    public class Adapter implements Target{
        // 适配者是对象适配器的一个属性
        private Adaptee adaptee = new Adaptee();
    
        @Override
        public void request() {
            //...
            adaptee.adapteeRequest();
            //...
        }
    }
    

    注意这里的 Adapter 是将 Adaptee 作为一个成员属性,而不是继承它。

    1.5其他

    对于类适配器,由于java是单继承的,所以一次只能适配(继承)一个对象。目标抽象类只能为接口,不能为类。(实现
    对于对象适配器,置换适配者类的某些方法比较复杂。

    1.6适配器运用实例

    在Spring的Aop中,使用的 Advice(通知) 来增强被代理类的功能。
    Advice的类型有:MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice。在每个类型 Advice 都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。Spring需要将每个 Advice 都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对 Advice 进行转换。

    //三个适配者类 Adaptee
    public interface MethodBeforeAdvice extends BeforeAdvice {
        void before(Method var1, Object[] var2, @Nullable Object var3) throws Throwable;
    }
    
    public interface AfterReturningAdvice extends AfterAdvice {
        void afterReturning(@Nullable Object var1, Method var2, Object[] var3, @Nullable Object var4) throws Throwable;
    }
    
    public interface ThrowsAdvice extends AfterAdvice {
    }
    
    

    目标接口 Target,有两个方法,一个判断 Advice 类型是否匹配,一个是工厂方法,创建对应类型的 Advice 对应的拦截器

    public interface AdvisorAdapter {
        boolean supportsAdvice(Advice var1);
    
        MethodInterceptor getInterceptor(Advisor var1);
    }
    
    

    三个适配器类 Adapter 分别如下

    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);
    	}
    }
    
    @SuppressWarnings("serial")
    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());
    	}
    }
    
    

    spring JPA中的适配器模式:首先定义了一个接口的 JpaVendorAdapter,然后不同的持久层框架都实现此接口。
    spring MVC中的适配器模式:在Spring MVC中,DispatcherServlet 作为用户,HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。通过适配器模式我们将所有的 controller 统一交给 HandlerAdapter 处理,免去了写大量的 if-else 语句对 Controller 进行判断,也更利于扩展新的 Controller 类型。