介绍:

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; }​@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 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种经典形式