介绍:
1、适配器模式将某个类的接口转换成客户端期望的另一种接口表示 2、目的:兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为:包装器。 3、属于:结构型模式 4、分3类:1)类适配器2)对象适配器3)接口适配器 5、解耦。用户也只会看到源头和结果。目标 《- 适配器 《- 被适配器者
类适配器
介绍:
1、类适配器模式介绍 基本介绍:Adapter类,通过继承src类,实现dst类接口,完成src -> dst的适配
例子:
//1、统一的播放器接口
interface MediaPlayer {void play();
}
//2、两种不同的音频播放器
class AdvancedMusicPlayer {void playAdvancedMusic() {System.out.println("Playing advanced music");}
}
class SimpleMusicPlayer {void playSimpleMusic() {System.out.println("Playing simple music");}
}
//3、类适配器。Adapter类,通过继承src类,实现dst类接口,完成src -> dst的适配
class ClassAdapter extends AdvancedMusicPlayer implements MediaPlayer {@Overridepublic void play() {playAdvancedMusic();}
}
//4、使用类适配器MediaPlayer classAdapter = new ClassAdapter();classAdapter.play();
注意事项和细节
1、Java是单继承的,所以类适配器需要继承src类这是一个缺点,因为这要求了dst必须是接口,有局限性 2、src类的方法在Adapter中都会暴露出来,也增加了使用成本 3、由于其继承了src类,所以它可以根据需求重写src类方法,使Adapter灵活性增强了
对象适配器
介绍
1、基本思路和类适配器相同,只是将Adapter类做了修改,不是继承src类,而是持有src类的实例,以解决兼容性问题。 即:持有src类,实现dst类接口,完成src -> dst的适配 2、根据合成复用原则,在系统中尽量使用关联关系代替继承关系
例子
//1、统一的播放器接口
interface MediaPlayer {void play();
}
//2、两种不同的音频播放器
class AdvancedMusicPlayer {void playAdvancedMusic() {System.out.println("Playing advanced music");}
}
class SimpleMusicPlayer {void playSimpleMusic() {System.out.println("Playing simple music");}
}
//3、对象适配器:Adapter类做了修改,不是继承src类,而是持有src类的实例,以解决兼容性问题。
class ObjectAdapter implements MediaPlayer {//src类实例private AdvancedMusicPlayer advancedPlayer;public ObjectAdapter(AdvancedMusicPlayer advancedPlayer) {this.advancedPlayer = advancedPlayer;}
@Overridepublic void play() {advancedPlayer.playAdvancedMusic();}
}
// 4、使用对象适配器AdvancedMusicPlayer advancedPlayer = new AdvancedMusicPlayer();SimpleMusicPlayer simplePlayer = new SimpleMusicPlayer();MediaPlayer objectAdapter = new ObjectAdapter(advancedPlayer);objectAdapter.play();
注意事项和细节
1、对象适配器和类适配器是同一种思想,只是实现不同。根据合成复用原则,使用组合替代继承,它解决了类适配器必须继承src的局限性问题,也不要求dst必须是接口 2、使用成本更低,更灵活
接口适配器
介绍
1、适配器模式又称缺省适配器模式 2、当不需要全部实现接口提供方法时,可先设计一个抽象类实现接口,并为改接口中每一个方法提供一个默认实现(空方法),那么该抽象类子类可以选择性的覆盖父类方法 3、适用于一个接口不想使用所有方法情况
例子
//1、统一的播放器接口
interface Player {void play();void stop();void pause();
}
//2、创建一个抽象类,实现Player接口(默认空方法实现)
abstract class PlayerAdapter implements Player {@Overridepublic void play() {}
@Overridepublic void stop() {}
@Overridepublic void pause() {}
}
//3、创建具体的适配器类,只需重写方法即可
class SimplePlayerAdapter extends PlayerAdapter {@Overridepublic void play() {System.out.println("Simple player is playing");}
}
class AdvancedPlayerAdapter extends PlayerAdapter {@Overridepublic void play() {System.out.println("Advanced player is playing");}
@Overridepublic void stop() {System.out.println("Advanced player is stopped");}
@Overridepublic void pause() {System.out.println("Advanced player is paused");}
}
//4、接口适配器使用
public class InterfaceAdapterExample {public static void main(String[] args) {Player simplePlayer = new SimplePlayerAdapter();simplePlayer.play();
Player advancedPlayer = new AdvancedPlayerAdapter();advancedPlayer.play();advancedPlayer.stop();advancedPlayer.pause();}
}
适配器模式在SpringMVC框架应用的源码分析
适配器模式在SpringMVC框架应用的源码剖析
1、SpringMVC中的HandlerAdapter使用到了适配器模式 2、SpringMVC请求处理的流程回顾 3、使用HandlerAdapter的原因分析
模拟实现
1、Controller接口
package com.pxl.testinterface.SpringMVCTest;
public interface Controller {
}
class HttpController implements Controller{public void doHttpHandler(){System.out.println("http...");}
}
class SimpleController implements Controller{public void doHttpHandler(){System.out.println("simple...");}
}
2、适配器处理
package com.pxl.testinterface.SpringMVCTest;
public interface HandlerAdapter {boolean supports(Object handler);void handle( Object handler);
}
class SimpleHandlerAdapter implements HandlerAdapter {public boolean supports(Object handler) {return handler instanceof SimpleController;}public void handle(Object handler) {((SimpleController)handler).doHttpHandler();}
}
class HttpHandlerAdapter implements HandlerAdapter {public boolean supports(Object handler) {return handler instanceof HttpController;}public void handle(Object handler) {((HttpController)handler).doHttpHandler();}
}
3、调用方
package com.pxl.testinterface.SpringMVCTest;
import java.util.ArrayList;
import java.util.List;
public class DispatcherServlet {public static List<HandlerAdapter> handlerAdapterList = new ArrayList<>();public DispatcherServlet(){handlerAdapterList.add(new HttpHandlerAdapter());handlerAdapterList.add(new SimpleHandlerAdapter());}
public void doDispatch(){//此处是模拟SpringMVC从request中获得handler对象//适配器可以获取到希望得ControllerHttpController controller = new HttpController();
//得到对应适配器HandlerAdapter adapter = getHandler(controller);adapter.handle(controller);
}public HandlerAdapter getHandler(Controller controller){for (HandlerAdapter adapter : this.handlerAdapterList) {if (adapter.supports(controller)){return adapter;}}return null;}
public static void main(String[] args) {new DispatcherServlet().doDispatch();}
}
总结
自己的理解:
当客户端调用适配器时,适配器会返回给客户端一个符合客户端期望的接口的类实例。这样客户端就可以通过适配器来获取想要的类,而无需关心具体的实现细节。 精简: 我调用Adapter,Adapter返回给我一个想要的类
注意事项和细节
1、三种命名方式,是根据src是以怎样的形式给到Adapter(在Adapter的形式)来命名 2、1)类适配器:以类给到,在Adapter里,将src当作类,继承2)对象适配器:以对象给到,在Adapter里,将src作为对象,持有3)接口适配器:以接口给到,在Adapter里,将src作为一个接口,实现 3、Adapter模式最大作用:将原本不兼容的接口融合一起工作 4、实际开发中不仅仅是我们将的3种经典形式