适配器模式,Adapter模式,也叫Wrapper模式(包装器)

Adapter这个词见的很多,比如springmvc里的SimpleControllerHandlerAdapter,slf4j里的AbstractLoggerAdapter

顾名思义:适配器是为目标寻找合适的类的方法或者对找到的方法进行改造(重写)从而完成方法的调用

适配器模式具体又分为两种:类适配器模式和对象适配器模式

本篇讲的是类适配器模式,对象适配器模式下次再说

类适配器模式对应继承关系

涉及到这几个角色:

Target:目标接口,需要一个method2方法的实现

Adaptee:被适配者(可以是类或者接口),仅有一个method1方法

Adapter:适配器,实现了Target接口,并继承了Adaptee方法

(图不重要看字)

spring mvc 处理器映射器处理器适配器视图解析器 spring中适配器模式_子类

 

 具体的以slf4j中 LoggerFactory.getLogger(..)方法来说明

spring mvc 处理器映射器处理器适配器视图解析器 spring中适配器模式_抽象类_02

可以看到iLoggerFactory调用了其实现类Log4jLoggerFactory的getLogger方法,于是进入LoggerFactory

spring mvc 处理器映射器处理器适配器视图解析器 spring中适配器模式_适配器模式_03

令人意外的是该类中并没有getLogger方法,别急,注意红色标注的地方,先进入AbstractLoggerAdapter,可以看到在此类中有一个getLogger方法,此外这个抽象类还实现了一个LoggerAdapter接口

 

spring mvc 处理器映射器处理器适配器视图解析器 spring中适配器模式_子类_04

LoggerAdapter接口的代码就不贴了,里面只有一个getLogger方法

所以iLoggerFactory.getLogger(name)调用的过程就很清楚了:调用的是Log4jLoggerFactory从AbstractLoggerAdapter继承的getLogger方法

结合我们开头的Target,此处指的就是iLoggerFactory,他需要一个getLogger方法,而LoggerAdapter(Adaptee)接口里有这个方法,但接口里的方法不能直接调用,

于是有一个抽象类AbstractLoggerAdapter实现了iLoggerFactory接口,并重写了其getLogger方法,但真正充当适配器角色的是AbstractLoggerAdapter的子类

Log4jLoggerFactory,iLoggerFactory通过它真正的调用了getLogger方法,

spring mvc 处理器映射器处理器适配器视图解析器 spring中适配器模式_子类_05

 事实上,这之间还隐藏着一种被称为缺省适配的模式,即当一个接口(类)A想调用另一个接口B的某个方法时,直接写个类实现B接口的话,那么要实现B接口里的全部方法

这样我们虽然可以调用方法了,但却要实现相当多的冗余方法,通常的做法是使用一个抽象类C继承B接口,实现其方法(多数为空的方法体,有人称之为平庸的实现),再使用一个新的类继承C.

这样就可以直接调用(改造)我们需要的方法,你可能会说,这并没有简便,事实上编写抽象类继承接口的大多数工作java已经替我们完成了,我们需要做的只是继承该抽象类

 

到此类对象适配器模式就结束了,可以看到类适配器模式使用的是继承关系,这使得我们调用Adaptee的方法,只能静态的使用其一个子类

这是由继承决定的无法避免,如果我们希望动态的使用Adaptee的方法,即可以动态的选择其子类来调用我们的方法该怎么做呢?这就要用

到对象适配器模式了,下次再说