1 基础知识

定义:将一个类的接口(被适配者)转换成客户期望的另一个接口(目标)。特征:使原本接口不兼容的类可以一起工作。

本质:转换匹配,复用功能。把不兼容的接口转换为客户端期望的样子从而实现功能的复用。

使用场景:已经存在的类,它的方法(接口)和需求不匹配时的解决方案。注意适配器模式不是软件设计阶段需要考虑的设计模式,而是随着软件维护,由于不同产品不同厂家造成功能类似而接口不相同情况下的解决方案。

优点:

更好的复用:性如果功能是已经有了的,只是接口不兼容,那么通过适配器模式就可以让这些功能得到更好的复用。

更好的可扩展性:在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

缺点:过多地使用适配器,会让系统非常零乱,不容易整体进行把握比如,明明看到调用的是A接口,其实内部被适配成了B接口来实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

2 代码示例

适配器的两种实现方式:

类适配器:

被适配者类:Adaptee

public class Adaptee {
public void adapteeRequest(){
System.out.println("被适配者的方法");
} }

目标接口:Target

public interface Target {
void request();
}

目标实现:

public class ConcreteTarget implements Target {
@Override
public void request() {
System.out.println("concreteTarget目标方法");
}
}

适配者类:Adapter  通过继承和实现将被适配者类和目标联系在了一起

public class Adapter extends Adaptee implements Target{
@Override
public void request() { //在此方法体内可以添加需要的代码 super.adapteeRequest();
}
}

应用层:

public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
//目标方法输出
target.request(); Target adapterTarget = new Adapter();
//适配者方法输出
adapterTarget.request();
}
}

其类图关系如下:

对象适配器:

修改适配者类:

public class Adapter implements Target{
//通过组合方式而不是继承
private Adaptee adaptee = new Adaptee(); @Override
public void request() { //添加自己需要代码 adaptee.adapteeRequest();
}
}

应用层代码不变直接测试即可,其类关系图如下图,在代码中有一个原则如果继承和组合都可以满足要求优先选择组合。

场景使用:生活中的手机充电,需要把220V转换为5V电源。

220V电源:被适配者

public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出交流电"+output+"V");
return output;
}
}

目标接口:5V电源

public interface DC5 {
int outputDC5V();
}

适配者:

public class PowerAdapter implements DC5{
private AC220 ac220 = new AC220(); @Override
public int outputDC5V() {
int adapterInput = ac220.outputAC220V();
//变压器...
int adapterOutput = adapterInput/44; System.out.println("使用PowerAdapter输入AC:"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
return adapterOutput;
}
}

应用层:

public class Test {
public static void main(String[] args) {
DC5 dc5 = new PowerAdapter();
dc5.outputDC5V();
}
}

在实际开发中场景:如一个日志记录系统最初的的版本1:LogMode1 只有两个简单的功能以文件的形式读日志和写日志。

public interface LogMode1 {
public void writeLogFile();
public void readLogFile();
}

随着使用升级系统便有了版本2:将日志保存到数据库中可以对其进行增删改查

public interface LogMode12 {
//新增日志
public void creatLogFile();
//修改日志
public void updateLogFile();
//删除日志
public void removeLogFile();
//获取所有日志
public List<LogFile> getLogFile();
}

此时客户端提出需求,能否让版本2同时支持数据库存储和文件存储?直接的思路是进行合并但是有问题,现在客户端操作的第二版的日志接口,但第一版的接口与第二版的不同,客户端无法以同样的方式使用第一版的实现,如下图所示:

简单粗暴的方法是在第二版中增加文件存储功能,但是这些功能在第一版中已经实现过了,因此要避免重复劳动。解决方法就是采用适配器模式:Target接口相当于第二版的日志接口,被适配者则是第一版接口,采用类似前面提供的代码即可解决。

3 源代码中的使用

4 相关设计模式

(1)适配器模式与桥接模式

其实这两个模式除了结构略为相似外,功能上完全不同。适配器模式是把两个或者多个接口的功能进行转换匹配;而桥接模式是让接口和实现部分相分离,以便它们可以相对独立地变化。

(2)适配器模式与装饰模式

从某种意义上讲,适配器模式能模拟实现简单的装饰模式的功能,也就是为已有功能增添新功能,因为在适配器里可以添加功能。但仅仅是类似,造成这种类似的原因是:两种设计模式在实现上都是使意用的对象组合,都可以在转调组合对象的功能前后进行一些附加的处理,因此有这么一个相似性。它们的目的和本质都是不一样的。两个模式有一个很大的不同:一般适配器适配过后是需要改变接口的,如果不改接口就没有必要适配了;而装饰模式是不改变接口的,无论多少层装饰都是一个接口。因此装饰模式可以很容易地支持递归组合,而适配器就做不到,每次的接口不同,无法递归。

(3)适配器模式和代模式

适配器模式可以和代理模式组合使用。在实现近配器的时候,可以通过代理来调用 Adaptee,这样可以获得更大的灵活性。

(4)适配器模式和抽象工厂模式。

在适配器实现的时候,通常需要得到被适配的对象。如果被适配的是一个接口,那么就可以结合一些可以创造对象实例的设计模式,来得到被适配的对象示例,比如抽象工厂模式、单例模式、工厂方法模式等。

0

适配器模式(Adapter)---结构型的更多相关文章

  1. 适配器模式 adapter 结构型 设计模式(九)

    现实世界中的适配器模型   先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座   上图为插座适配器卖家的描述图   上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电 ...

  2. 设计模式06: Adapter 适配器模式(结构型模式)

    Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...

  3. Java设计模式06:常用设计模式之适配器模式(结构型模式)

    1. Java之适配器模式(Adapter Pattern) (1)概述:    将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起 ...

  4. C#设计模式--适配器模式(结构型模式)

    一.适配器模式介绍: 适配器模式:将一个类的接口,转换成客户希望的另外一个接口.adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 例子分析(充电器充电): 模式中的角色: 安 ...

  5. 设计模式之适配器模式(Adapter)

    适配器模式原理:适配器模式属于结构型模式,主要作用是完成功能的转换, 1.通过一个类继承目标类. 2.需要适配的类 3.适配器 代码如下: #include <iostream> usin ...

  6. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

  7. C#设计模式之七适配器模式(Adapter)【结构型】

    一.引言   从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题, ...

  8. C#设计模式之六适配器模式(Adapter Pattern)【结构型】

    一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...

  9. NET设计模式 第三部分 结构型模式(7):适配器模式(Adapter Pattern)

    适配器模式(Adapter Pattern) ——.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但 ...

  10. 初探Java设计模式2:结构型模式(代理模式,适配器模式等)

    行为型模式 行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰. 策略模式 策略模式太常用了,所以把它放到最前面进行介绍.它比较简单,我就不废话,直接用代码说事吧. 下面 ...

随机推荐

  1. 【数据库-SQL Server】IDispatch error #3092

    使用msado15.tlh,链接Microsoft SQL Server,执行语法(syntax)的时候出现IDispatch error #3092的错误. 1.语法错误 (1)保证语法正确,有些数 ...

  2. 级联-city

    <!DOCTYPE html><html> <head>  <meta charset="UTF-8">  <title> ...

  3. Ubuntu系统降内核

    本人安装的Ubuntu16.04.6系统原生内核为4.15.0,但安装的应用仅支持4.8.0以下内核,因此需要降内核.PS:降内核有风险,操作前请慎重 1.查看可用的内核 输入命令查看已经可用的内核 ...

  4. 微信小程序 基本介绍及组件

    创建项目 微信开发工具深入介绍 https://developers.weixin.qq.com/miniprogram/dev/devtools/devtools.html 基本项目目录 1. 配置 ...

  5. Python---通配符的使用

    苹果单价 9.00 元/斤,购买了 5.00 斤,需要支付 45.00 元 在 Python 中可以使用 print 函数将信息输出到控制台 如果希望输出文字信息的同时,一起输出 数据,就需要使用到  ...

  6. maven中添加memcached.jar配置方法

    一.java memcached client的jar包下载地址:https://github.com/gwhalin/Memcached-Java-Client/downloads 二.cd jav ...

  7. hdu 1305 还是字典树

    #include<cstdio> #include<iostream> #include<string> #include<cstdlib> #defi ...

  8. request.getScheme() 使用方法(转)

    今天在看代码时,发现程序使用了 request.getScheme() .不明白是什么意思,查了一下.结果整理如下: 1.request.getScheme() 返回当前链接使用的协议:一般应用返回h ...

  9. C#进阶之WebAPI(三)

    今天复习一下WebAPI的路由知识: 首先分析一下MVC路由和WebAPI路由的区别: 在mvc里,默认的路由机制是通过URL路径去匹配控制器和Action方法的,在mvc中的默认路由定义在App_S ...

  10. faceswap深度学习AI实现视频换脸详解

    给大家介绍最近超级火的黑科技应用deepfake,这是一个实现图片和视频换脸的app.前段时间神奇女侠加尔盖朵的脸被换到了爱情动作片上,233333.我们这里将会从github项目faceswap开始 ...