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 {
- @Override
- public 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;
- }
-
- @Override
- public 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 {
- @Override
- public void play() {}
-
- @Override
- public void stop() {}
-
- @Override
- public void pause() {}
- }
-
-
- //3、创建具体的适配器类,只需重写方法即可
- class SimplePlayerAdapter extends PlayerAdapter {
- @Override
- public void play() {
- System.out.println("Simple player is playing");
- }
- }
-
- class AdvancedPlayerAdapter extends PlayerAdapter {
- @Override
- public void play() {
- System.out.println("Advanced player is playing");
- }
-
- @Override
- public void stop() {
- System.out.println("Advanced player is stopped");
- }
-
- @Override
- public 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框架应用的源码剖析
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
handlerAdapterList = new ArrayList<>(); - public DispatcherServlet(){
- handlerAdapterList.add(new HttpHandlerAdapter());
- handlerAdapterList.add(new SimpleHandlerAdapter());
- }
-
- public void doDispatch(){
- //此处是模拟SpringMVC从request中获得handler对象
- //适配器可以获取到希望得Controller
- HttpController 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种经典形式