Java描述设计模式(07):适配器模式
本文源码: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):适配器模式的更多相关文章
- Java常见设计模式之适配器模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...
- Java描述设计模式(11):观察者模式
本文源码:GitHub·点这里 || GitEE·点这里 一.观察者模式 1.概念描述 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.观察者模式定义了一种一对多 ...
- Java描述设计模式(09):装饰模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 孙悟空有七十二般变化,他的每一种变化都给他带来一种附加的本领.他变成鱼儿时,就可以到水里游泳:他变成鸟儿时,就可以 ...
- 基于JAVA的设计模式之适配器模式
适配器模式概念 适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.比如我们突然就想看电影了,但是这个电影是AVI格式的,目前我们开发 ...
- Java描述设计模式(15):责任链模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景描述 1.请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批 当 3<day<= ...
- Java描述设计模式(24):备忘录模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 常见的视频播放软件都具备这样一个功能:假设在播放视频西游记,如果这时候切换播放视频红楼梦,当再次切回播放西游记时, ...
- Java描述设计模式(12):外观模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在移动互联网没有普及之前,去饭店吃饭的流程大致如下:选座位,排队,点菜,结账.后来移动互联网普及,通过手机APP就 ...
- Java描述设计模式(08):桥接模式
本文源码:GitHub·点这里 || GitEE·点这里 一.桥接模式简介 1.基础描述 桥梁模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥 ...
- Java描述设计模式(05):原型模式
本文源码:GitHub·点这里 || GitEE·点这里 一.原型模式简介 1.基础概念 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出 ...
随机推荐
- 安装mysql5.7(亲手实操)
https://files-cdn.cnblogs.com/files/yucoder/%E5%AE%89%E8%A3%85mysql5.7.pdf
- native C++ 动态调用.NET DLL
关于这个问题找了好多地方,都只有第二种解决办法,可是我要返回一个字符串,没办法,继续找,最后还是在http://blogs.msdn.com/b/msdnforum/archive/2010/07/0 ...
- NodeJS7-1本地构建_gulp入门学习
NodeJS在前端最常用的两种方式: 1.做成webserver 2.做成前端开发的相关工具 本地构建:前端发布代码都会经过压缩(谁来处理) ,前端技术的日新月异,利用新特性代码变得易读,清晰,可是老 ...
- dev gridcontrol 行号
/// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...
- 《Java基础知识》Java常量的申明和使用
常量就是从程序开始运行到结束都不变的量.在 Java 程序设计中,使用关键字“final”来声明一个常量,例如下面的程序代码. 这里的 x 是一个常量,但是是在某个方法内的常量,也可以称为成员常量(作 ...
- Microsemi Libero使用技巧——使用FlashPro生成stp程序文件
前言 在工程代码编译完成之后,如果需要给某个芯片下载程序时,或者是工厂量产烧录程序时,我们不需要把整个工程文件给别人,而只需要把生成的下载文件给别人,然后使用FlashPro就可以单独下载程序文件了. ...
- Android Activity启动流程, app启动流程,APK打包流程, APK安装过程
1.Activity启动流程 (7.0版本之前) 从startActivity()开始,最终都会调用startActivityForResult() 在该方法里面会调用Instrumentation. ...
- Linux - CentOS 7 通过Yum源安装 MySql 5.7
添加MySQL Yum存储库 从官网下载最新的mysql源 官网地址:https://dev.mysql.com/downloads/repo/yum/ 选择并下载适用于平台的发行包. 然后,在Lin ...
- web中状态码301和302的区别
web中状态码301和302的区别 总的区别就是:302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的.而301重定向是永久 ...
- Python 的 Geth 封装库 PyGeth
PyGeth 是一个 Python 封装库,用来作为子进程运行 geth. 系统依赖 该库需要 geth 可执行文件. 安装 pip install py-geth 快速启动 运行连接到 mainne ...