目录
一、适配器模式
1、适配器模式(Adapeter Pattern)将某个类的接口转换成客户端期待的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,又称包装器。
2、适配器模式属于结构型模式
3、主要有三种:类适配器模式、对象适配器模式、接口适配器模式。
二、适配器模式工作原理
1、将一个类的接口转换成另一个接口,让原本接口不兼容的类可以兼容。
2、从用户的角度看不到被适配者,是解耦的。
3、用户调用适配器转化出来的目标接口方法,适配器再被适配者的相关接口方法。
4、用户收到反馈结果,只是觉得和目标结果交互。
三、三种适配器模式的实现
3.1、类适配器模式
Adapter类通过继承src类,实现dst类接口,完成适配。
问题需求:220v的交流电需要是充电器适配给需要5v交流电的手机。
示例参考代码:
//被适配类
public class Voltage {
public int output220(){
int src = 220;
return src;
}
}
//适配接口
public interface IVoltage {
public int output5();
}
public class VoltageAdapter extends Voltage implements IVoltage {
@Override
public int output5() {
//获取220v
int srcV = super.output220();
int dstV = srcV / 44; //转换为5v电压
return dstV;
}
}
public class Phone {
//充电
public void charging(IVoltage iVoltage){
int src = iVoltage.output5();
if (src == 5){
System.out.println("可以正常充电");
}else {
System.out.println("不可以正常充电");
}
}
}
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
代码分析:
1、Java是单继承机制,所以类适配器需要继承Voltage类是一个缺点,因为IVoltage必须是接口,有一定局限性。
2、Voltage类的方法会在VoltageAdapter类暴露出来,增加了使用成本。
3、因为继承了Voltage类,所以可以根据需要重写Voltage类的方法,使VoltageAdapter类更加灵活
3.2、对象适配器模式
1、将VoltageAdapter做修改,不再继承Voltage类,而是持有Voltage类,解决兼容性的问题。
2、根据“合成复用原则”,尽量使用关联关系替代继承关系。
3、对象适配器模式是适配器模式常用一种。
示例参考代码:
其他代码不变,只需要修改这两个类:
public class VoltageAdapter implements IVoltage {
private Voltage voltage;
//通过构造器传入Voltage实例
public VoltageAdapter(Voltage voltage) {
this.voltage = voltage;
}
@Override
public int output5() {
int dst = 0;
if (voltage != null){
int src = voltage.output220();
dst = src / 44;
}
return dst;
}
}
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage()));
}
}
代码分析:
1、对象适配器与类适配器思想相同,只是实现方式不同。根据合成复用原则,使用组合替代继承,解决了类适配器必须继承的局限性问题,不再要求IVoltage为接口。
2、使用成本更低,更灵活。
3.3、接口适配器模式
1、当不需要全部实现接口提供的方法时,设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
2、适合使用于一个接口不想使用其所有的方法的情况。
示例参考代码:
public interface Interface1 {
public void m1();
public void m2();
public void m3();
}
//对Interface1的方法进行默认实现
public abstract class AbsAdepter implements Interface1 {
@Override
public void m1() {
}
@Override
public void m2() {
}
@Override
public void m3() {
}
}
public class Client {
public static void main(String[] args) {
AbsAdepter absAdepter = new AbsAdepter(){
@Override
public void m1() {
super.m1();
System.out.println("m1方法使用");
}
};
absAdepter.m1();
}
}
四、适配器模式在springMVC中的使用
1、springMVC中的HandlerAdapter中使用
当请求过来时会在DispatcherServlet调用doDispatch方法
mappedHandler相当于控制器,通过mappedHandler调用getHandler方法返回一个适配器
在这里会返回一个适配器
通过得到的适配器调用handle方法。
模拟springmvc通过适配器获取对应controller的源码
参考代码实现:
//多种Controller实现
public interface Controller {
}
class HttpController implements Controller{
public void doHttpHandler(){
System.out.println("http...");
}
}
class SimpleController implements Controller{
public void doSimplerHandler(){
System.out.println("simple...");
}
}
class AnnotationController implements Controller{
public void doAnnotationHandler(){
System.out.println("annotation...");
}
}
//定义一个Adepter接口
public interface HandlerAdepter {
public boolean supports(Object handler);
public void handler(Object handler);
}
//多种适配器类
class SimpleHandlerAdepter implements HandlerAdepter{
@Override
public boolean supports(Object handler) {
return (handler instanceof SimpleController);
}
@Override
public void handler(Object handler) {
((SimpleController) handler).doSimplerHandler();
}
}
class AnnotationHandlerAdepter implements HandlerAdepter{
@Override
public boolean supports(Object handler) {
return (handler instanceof AnnotationController);
}
@Override
public void handler(Object handler) {
((AnnotationController) handler).doAnnotationHandler();
}
}
class HttpHandlerAdepter implements HandlerAdepter{
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpController);
}
@Override
public void handler(Object handler) {
((HttpController) handler).doHttpHandler();
}
}
public class DispatchServlet {
public static void main(String[] args) {
new DispatchServlet().doDispatch();
}
public static List<HandlerAdepter> handlerAdepters = new ArrayList<>();
public DispatchServlet() {
handlerAdepters.add(new AnnotationHandlerAdepter());
handlerAdepters.add(new HttpHandlerAdepter());
handlerAdepters.add(new SimpleHandlerAdepter());
}
public void doDispatch(){
//模拟SpringMVC从request取handler的对象
//适配器可以获取到希望的controller
AnnotationController annotationController = new AnnotationController();
//得到对应的适配器
HandlerAdepter handler = getHandler(annotationController);
//通过适配器执行对应的controller代码
handler.handler(annotationController);
}
public HandlerAdepter getHandler(Controller controller){
for (HandlerAdepter adepter: this.handlerAdepters) {
if (adepter.supports(controller)){
return adepter;
}
}
return null;
}
}
1、springMVC定义一个适配器接口,使得每一种Controller有一种对应的适配器实现类适配器代替controller执行相应的方法。
2、在扩展Controller时,只需要增加一个适配器类就完成了springMVC的扩展。
五、适配器的注意实现
1、三种命名方式,是根据src是以怎样的形式给到Adapter来命令。
2、类适配器:以类给到,在Adapter里,就是将src当做类,继承。
对象适配器:以对像给到,在Adapter里 ,将src作为一个对象,持有。
接口适配器:以接口给到。在Adapter里,将src作为一个接口,实现。
3、Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。