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. 如何判断你的windows系统是32位还是64位?

    [学习笔记] 如 何判断你的windows系统是32位还是64位? java -version时,如果没有64就是32位的.eclipse.ini中如果没有64,就是32位的.但是我们的ini文件里面 ...

  2. Linux (x86) Exploit 开发系列教程之四(使用return-to-libc绕过NX bit)

    (1)原理: “NX Bit”的漏洞缓解:使某些内存区域不可执行,并使可执行区域不可写.示例:使数据,堆栈和堆段不可执行,而代码段不可写. 在NX bit打开的情况下,基于堆栈的缓冲区溢出的经典方法将 ...

  3. 以太坊再爆高危漏洞!黑客增发ATN 1100万枚token事件始末

    事情发生在5月中旬,ATN技术人员发现Token合约由于存在漏洞受到攻击.不过ATN基金会随后透露,将销毁1100万个ATN,并恢复ATN总量,同时将在主链上线映射时对黑客地址内的资产予以剔除,确保原 ...

  4. 服务器上office不能正常使用?

    (1)确保dll版本和服务器上office版本一致 (2)配置dcom (3)项目配置文件中添加用户模拟语句 <system.web> <identity impersonate=& ...

  5. ORM框架之EntityFramework介绍

    ORM框架之EntityFramework介绍 1. 简介 大家好!我是高堂. 作为一位伪前端程序猿,我给大家介绍一下微软的自家的 ORM框架. ADO.NET Entity Framework 以下 ...

  6. Vim 添加vimgdb支持

    ./configure --enable-gdb --prefix=/usr --enable-multibyte --enable-fontset --enable-xim --enable-gui ...

  7. c# internal关键字

    对于一些大型的项目,通常由很多个DLL文件组成,引用了这些DLL,就能访问DLL里面的类和类里面的方法.比如,你写了一个记录日志的DLL,任何项目只要引用此DLL就能实现记录日志的功能,这个DLL文件 ...

  8. SqlServer 附加数据库出错

    方法一 找到要添加数据库的.mdf文件,点击右键,选择属性 在属性页面点击安全,选择Authenticated Users,单击编辑 Authenticated Users权限中选择完全控制,点击确定 ...

  9. js重点——作用域——作用域分类(三)

    一.作用域可以分为全局作用域,局部作用域(函数作用域)和块级作用域. 1.全局作用域 代码在程序中的任何位置都能被访问到,window对象的内置属性都拥有全局作用域. <script> v ...

  10. BFC渲染机制

    BFC(block formatting context):块级格式化上下文(实际就是一个隔离罩) W3C CSS2.1 规范中的一个概念.它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元 ...