本文源码:GitHub·点这里 || GitEE·点这里

一、适配器模式简介

1、基础概念

适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式有类适配器模式和对象适配器模式,以及缺省(接口)适配器,三种不同的形式。

2、生活场景

基于适配器模式,把220V的电压,转换为需要的110V电压。

public class C01_InScene {
public static void main(String[] args) {
CurrentAdapter adapter = new CurrentAdapter() ;
System.out.println(adapter.get110VCurrent()) ;
}
}
// 220V电流
class Current220V {
public int get220VCurrent (){
return 220 ;
}
}
// 110V电流接口
interface Current110V {
int get110VCurrent () ;
}
// 电流适配器
class CurrentAdapter extends Current220V implements Current110V {
// 电流转换方法
@Override
public int get110VCurrent() {
int high = get220VCurrent() ;
int low = high/2 ;
return low ;
}
}

二、类适配器

1、模式简介

类的适配器模式把适配的类的API转换成为目标类的API。

2、核心角色

  • 目标(Target)角色

这就是所期待得到的接口。

  • 源(Adapee)角色:

现在需要适配的接口。

  • 适配器(Adaper)角色

适配器类是本模式的核心。适配器把源接口转换成目标接口。

3、源码实现

interface Target {
void sampleOperation1();
void sampleOperation2();
}
class Adaptee {
public void sampleOperation1(){
System.out.println("Adaptee.sampleOperation1()");
}
}
class Adapter extends Adaptee implements Target{ @Override
public void sampleOperation2() {
System.out.println("Adapter.sampleOperation2()");
}
}

三、对象适配器

1、模式简介

与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

2、源码实现

interface Target1 {
void sampleOperation1();
void sampleOperation2();
}
class Adaptee1 {
public void sampleOperation1(){
System.out.println("Adaptee.sampleOperation1()");
}
}
class Adapter1 implements Target1 {
private Adaptee1 adaptee ;
public Adapter1 (Adaptee1 adaptee){
this.adaptee = adaptee;
} public void sampleOperation1() {
this.adaptee.sampleOperation1();
} @Override
public void sampleOperation2() {
System.out.println("Adapter.sampleOperation2()");
}
}

四、接口适配器

1、模式简介

缺省(接口)适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。

2、源代码实现

public class C04_AdapterInte {
public static void main(String[] args) {
ServiceAdapter adapter = new ServiceAdapter(){
@Override
public int serviceOperation2() {
return 22 ;
}
};
System.out.println(adapter.serviceOperation2());
}
}
interface AbstractService {
void serviceOperation1();
int serviceOperation2();
String serviceOperation3();
}
class ServiceAdapter implements AbstractService{
@Override
public void serviceOperation1() { }
@Override
public int serviceOperation2() {
return 0;
}
@Override
public String serviceOperation3() {
return null;
}
}

五、Spring框架应用

1、应用场景描述

在SpringMvc执行控制执行请求的时候,有这样一个流程

1)前段控制器DispatcherServlet调用处理器适配器去执行Handler(也就是Controller);

2)处理器适配器去执行Handler,给适配器返回ModelAndView ;

3)处理器适配器向前端控制器返回ModelAndView ;

2、流程分析

  • 核心接口和实现

Controller和HandlerAdapter两核心接口。



  • HandlerAdapter

适配器接口,使Handler有对应的适配器实现类,适配器代替Handler(控制层Controller)执行相应的方法。

public interface HandlerAdapter {
// 判断类型是否匹配
boolean supports(Object var1);
// 执行方法,返回ModelAndView
ModelAndView handle(HttpServletRequest var1,
HttpServletResponse var2, Object var3)
throws Exception;
}

supports()方法传入处理器,判断适配器是否支持,如果支持则返回支持的适配器实现类。

  • DispatchServlert

抽取源码中体现流程的几个步骤。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
mappedHandler = this.getHandler(processedRequest);
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
  • SimpleControllerHandlerAdapter

最后看下supports和handle两个方法的具体实现。

public class SimpleControllerHandlerAdapter implements HandlerAdapter {
public SimpleControllerHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof Controller;
}
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
return ((Controller)handler).handleRequest(request, response);
}
}

六、适配器优缺点

1、优点分析

更好的复用性,系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。更好的扩展性。

2、缺点分析

过多的使用适配器,会让系统非常零乱,不易整体进行把控。

七、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

Java描述设计模式(07):适配器模式的更多相关文章

  1. Java常见设计模式之适配器模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...

  2. Java描述设计模式(11):观察者模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.观察者模式 1.概念描述 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.观察者模式定义了一种一对多 ...

  3. Java描述设计模式(09):装饰模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 孙悟空有七十二般变化,他的每一种变化都给他带来一种附加的本领.他变成鱼儿时,就可以到水里游泳:他变成鸟儿时,就可以 ...

  4. 基于JAVA的设计模式之适配器模式

    适配器模式概念 适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.比如我们突然就想看电影了,但是这个电影是AVI格式的,目前我们开发 ...

  5. Java描述设计模式(15):责任链模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景描述 1.请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批 当 3<day<= ...

  6. Java描述设计模式(24):备忘录模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 常见的视频播放软件都具备这样一个功能:假设在播放视频西游记,如果这时候切换播放视频红楼梦,当再次切回播放西游记时, ...

  7. Java描述设计模式(12):外观模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在移动互联网没有普及之前,去饭店吃饭的流程大致如下:选座位,排队,点菜,结账.后来移动互联网普及,通过手机APP就 ...

  8. Java描述设计模式(08):桥接模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.桥接模式简介 1.基础描述 桥梁模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥 ...

  9. Java描述设计模式(05):原型模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.原型模式简介 1.基础概念 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出 ...

随机推荐

  1. Kubernetes服务发现入门:如何高效管理服务?

    愈发复杂的应用程序正在依靠微服务来保持可扩展性和提升效率.Kubernetes为微服务提供了完美的环境,并能够让其与Kubernetes的工具组件和功能兼容.当应用程序的每个部分放置在一个容器中,整个 ...

  2. centos安装与配置keepalived+nginx高可用

    一.安装启动keepalived 1.下载keepalived 在centos系统中,用wget下载最新版本: mkdir tool cd tool wget https://www.keepaliv ...

  3. Nginx在开发中常用的基础命令

    场景 Ubuntu Server 16.04 LTS上怎样安装下载安装Nginx并启动: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/detai ...

  4. Linux下的密码破解

    密码散列: 密码散列的$6 表示是:SHA512 这里我们使用hashcat 工具进行破解 ╰─ hashcat -m 1800 hash.txt /usr/share/wordlists/rocky ...

  5. Qt在Android平台上实现html转PDF的功能

    Qt for Android Qt for Android enables you to run Qt 5 applications Android devices. All Qt modules ( ...

  6. 62-Weave 网络结构分析

    上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构. 在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 ...

  7. ORACLE数据库中执行计划出现INTERNAL_FUNCTION一定是隐式转换吗?

    ORACLE数据库中,我们会使用一些SQL语句找出存在隐式转换的问题SQL,其中网上流传的一个SQL语句如下,查询V$SQL_PLAN的字段FILTER_PREDICATES中是否存在INTERNAL ...

  8. [20191206]隐含参数_db_always_check_system_ts.txt

    [20191206]隐含参数_db_always_check_system_ts.txt --//今年年头我做tab$删除恢复时,遇到的问题,就是遇到延迟块清除的问题.参考链接:http://blog ...

  9. STM32F407外部晶体改为25M后检测不到芯片的解决办法

    问题描述 分享一个之前遇到的STM32F4晶体频率问题,导致单片机死机的解决办法.使用一款新的F4开发板,直接使用的正点原子STM32F407工程模板代码,管脚配置正确,下载到外部晶体为25MHz的开 ...

  10. Dubbo学习系列之十一(Dashboard+Nacos规则推送)

    中国武术,门派林立,都是号称多少代的XXX传人,结果在面对现代武术时,经常被KO秒杀,为啥,光靠宣传和口号撑门面,终究是靠不住,必须得有真货 ,得经得住考验,所以不能只说Sentinel有多好,也得给 ...