适配器模式

Posted jiezao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了适配器模式相关的知识,希望对你有一定的参考价值。

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 类型。






以上是关于适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数

如何从片段适配器启动活动

片段中ListView的android自定义适配器

设计模式之单例模式

片段内带有基本适配器的列表视图

片段中gridview的Android文本和图像适配器