结构型--适配器模式

一、什么是适配器模式

定义:适配器模式属于结构型模式,把一个类的接口变成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。

适配器模式又可以分为4种类型类适配器模式、对象适配器模式、单接口适配器模式(缺省适配器模式)和双向适配器模式。后2种模式的实现比较复杂并且在实际开发过程中很少使用。类适配器和对象适配器中,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

适配器优点:

1.能提高类的透明性和复用性,现有类的复用但不需要改变;

2.目标类和适配器类解耦合,提高程序扩展性;

3.符合开闭原则。

适配器缺点:

适配器模式编写过程中需要全面的考虑,可能会增加系统的复杂性,代码更难读懂。

 

二、适配器模式的结构

1、类适配器模式结构图

 

 2、对象适配器模式的结构图

 

 适配器模式(Adapter)包含以下主要角色:

Target:目标角色,定义了客户端期望的接口

Adaptee:适配者角色,实现了我们想要使用的功能,但是接口不匹配

Adapter:适配器角色,实现了目标接口。它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

三、模式实现示例

(1) 类适配器模式的代码如下。

package adapter;
//目标接口
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();
    }
}

程序的运行结果如下:

类适配器模式测试:
适配者中的业务代码被调用!


(2)对象适配器模式的代码如下。

package adapter;
//对象适配器类
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();
    }
}

说明:对象适配器模式中的“目标接口”和“适配者类”的代码同类适配器模式一样,只要修改适配器类和客户端的代码即可。

程序的运行结果如下:

对象适配器模式测试:
适配者中的业务代码被调用!

 四、在Spring中的应用

AOP和MVC中,都有用到适配器模式。

1. AOP中的应用
在Spring的Aop中,使用Advice(通知)来增强被代理类的功能,Advice的类型有:BeforeAdvice、AfterReturningAdvice、ThreowSadvice。

每种Advice都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。

各种不同类型的Interceptor,通过适配器统一对外提供接口,如下类图所示:client ---> target ---> adapter ---> interceptor ---> advice。最终调用不同的advice来实现被代理类的增强

 

 

2. MVC中的应用

DispatcherServlet中的doDispatch方法,是将请求分发到具体的controller,因为存在很多不同类型的controller,常规处理是用大量的if...else...,来判断各种不同类型的controller,如下这样:

if(mappedHandler.getHandler() instanceof MultiActionController){  
   ((MultiActionController)mappedHandler.getHandler()).xxx  
}else if(mappedHandler.getHandler() instanceof XXX){  
    ...  
}else if(...){  
   ...  
}

如果还需要添加另外的controller,就需要再次添加if...else...,程序就会难以维护,也违反了开闭原则 -- 对扩展开放,对修改关闭。

因此,spring定义了一个适配器接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了。

下图展示了DispatcherServlet类的关系图,因为使用了adapter

 

 

 

posted on 2012-06-05 15:44  duanxz  阅读(1815)  评论(0编辑  收藏  举报