设计模式-结构型模式之适配器模式(Adapter)

news2024/10/6 10:36:48

结构型模式简介

结构型模式(Structural Pattern)描述如何将类或者对 象结合在一起形成更大的结构,就像搭积木,可以通过 简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式可以分为类结构型模式对象结构型模式

类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。

对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继 承关系,因此大部分结构型模式都是对象结构型模式。

包含模式

适配器模式(Adapter)
桥接模式(Bridge)
组合模式(Composite)
装饰模式(Decorator)
外观模式(Facade)
享元模式(Flyweight)
代理模式(Proxy)

1. 适配器模式

1.1. 模式动机

  • 在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式

  • 通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。

  • 在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。

  • 在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类

  • 适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。

1.2. 模式定义

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为 包装器(Wrapper)。适配器模式 既可以作为类结构型模式也可以作为对象结构型模式

1.3. 模式结构

适配器模式包含如下角色:

  • Target:目标抽象类

  • Adapter:适配器类

  • Adaptee:适配者类

  • Client:客户类

适配器模式有对象适配器类适配器两种实现:

对象适配器:

类适配器:

1.4. 时序图

1.5. 代码分析

#include <iostream>
#include "Adapter.h"
#include "Adaptee.h"
#include "Target.h"

using namespace std;

int main(int argc, char *argv[])
{
    Adaptee * adaptee  = new Adaptee();
    Target * tar = new Adapter(adaptee);
    tar->request();
    
    return 0;
}
///
//  Adapter.h
//  Implementation of the Class Adapter
//  Created on:      03-十月-2014 17:32:00
//  Original author: colin
///

#if !defined(EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_)
#define EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_

#include "Target.h"
#include "Adaptee.h"

class Adapter : public Target
{

public:
    Adapter(Adaptee *adaptee);
    virtual ~Adapter();

    virtual void request();

private:
    Adaptee* m_pAdaptee;

};
#endif // !defined(EA_BD766D47_0C69_4131_B7B9_21DF78B1E80D__INCLUDED_)
///
//  Adapter.cpp
//  Implementation of the Class Adapter
//  Created on:      03-十月-2014 17:32:00
//  Original author: colin
///

#include "Adapter.h"

Adapter::Adapter(Adaptee * adaptee){
    m_pAdaptee =  adaptee;
}

Adapter::~Adapter(){

}

void Adapter::request(){
    m_pAdaptee->specificRequest();
}
///
//  Adaptee.h
//  Implementation of the Class Adaptee
//  Created on:      03-十月-2014 17:32:00
//  Original author: colin
///

#if !defined(EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_)
#define EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_

class Adaptee
{

public:
    Adaptee();
    virtual ~Adaptee();

    void specificRequest();

};
#endif // !defined(EA_826E6B4F_12BE_4609_A0A3_95BD5E657D36__INCLUDED_)

运行结果:

1.6. 优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。

  • 增加了类的透明性复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。

  • 灵活性扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

类适配器模式还具有如下优点:

由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的 灵活性更强

对象适配器模式还具有如下优点:

一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

1.7. 缺点

类适配器模式的缺点如下:

对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。

对象适配器模式的缺点如下:

与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。

1.8. 适用环境

在以下情况下可以使用适配器模式:

  • 系统需要使用现有的类,而这些类的接口不符合系统的需要。

  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

1.9. 模式应用

Sun公司在1996年公开了Java语言的数据库连接工具JDBC,JDBC使得Java语言程序能够与数据库连接,并使用SQL语言来查询和操作数据。JDBC给出一个客户端通用的抽象接口,每一个具体数据库引擎(如SQL Server、Oracle、MySQL等)的JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件。抽象的JDBC接口和各个数据库引擎API之间都需要相应的适配器软件,这就是为各个不同数据库引擎准备的驱动程序。

1.10. 模式扩展

认适配器模式(Default Adapter Pattern)或缺省适配器模式

当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求,它适用于一个接口不想使用其所有的方法的情况。因此也称为单接口适配器模式

1.11. 总结

  • 结构型模式描述如何将类或者对象结合在一起形成更大的结构

  • 适配器模式用于将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式

  • 适配器模式包含四个角色目标抽象类定义客户要用的特定领域的接口;适配器类可以调用另一个接口,作为一个转换器,对适配者和抽象目标类进行适配,它是适配器模式的核心适配者类是被适配的角色,它定义了一个已经存在的接口,这个接口需要适配;在客户类中针对目标抽象类进行编程,调用在目标抽象类中定义的业务方法。

  • 在类适配器模式中,适配器类实现了目标抽象类接口继承了适配者类,并在目标抽象类的实现方法中调用所继承的适配者类的方法;在对象适配器模式中,适配器类继承了目标抽象类并定义了一个适配者类的对象实例,在所继承的目标抽象类方法中调用适配者类的相应业务方法。

  • 适配器模式的主要优点将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合“开闭原则”;类适配器模式的缺点是适配器类在很多编程语言中不能同时适配多个适配者类,对象适配器模式的缺点是很难置换适配者类的方法

  • 适配器模式适用情况包括:系统需要使用现有的类,而这些类的接口不符合系统的需要;想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类一起工作。

[上一节]设计模式-创建型模式之单例模式

[下一节]设计模式-结构型模式之桥接模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/445245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot整合redis实现缓存

此次笔记是在实现了数据库的增删改查操作的基础上进行的&#xff0c;因此需要准备数据库、数据表&#xff0c;以及实现相对应的服务层、持久层、控制层。可参考之前的笔记Spring Boot整合 druid、Mybatis-plus 一、Redis安装 Redis 是完全开源免费的&#xff0c;遵守BSD协议&…

【每日一短语】对(某人)吹毛求疵

1、短语及释义 get all sensitive on sb. 释义&#xff1a; 对某人吹毛求疵。 sensitive: 敏感的&#xff0c;引申为“事多的”&#xff0c;“爱挑刺的”。 2、示例及出处 美剧&#xff1a;《摩登家庭》第4季第7集 Modern Family, Season 4 Episode 7 Jay Pritchett: Don’t g…

中医诊所一定要去尝试软文营销,效果简直不要太好

中医诊所是一种传统的医疗机构&#xff0c;随着互联网时代的发展&#xff0c;软文营销已经成为了中医诊所宣传推广的一种重要方式。通过撰写高质量的软文&#xff0c;中医诊所可以提升品牌知名度、增加患者数量、提高医疗服务质量等方面取得良好的效果。今天结合我10年营销经验…

INDEMIND双目惯性模组运行实时ORB-SLAM3教程

现在实验室视觉SLAM已经不够满足&#xff0c;所以需要多模态融合&#xff0c;正巧购入高翔博士推荐的INDEMIND双目惯性模组&#xff0c;根据官方例程在中使用ros接入ORB-SLAM3INDEMIND的双目鱼眼imu模组&#xff0c;这回有SDK及ORB-SLAM3安装过程中的各种常见性问题解决方法及安…

Boost的安装

过程 boost是一个非常重要的东西&#xff0c;是对C函数库的扩展&#xff0c;非常得不错&#xff0c;是第三方扩展&#xff0c;不过不是一般的第三方&#xff0c;是C标准委员会工作组成员发起的。 通过vs命令工具进入boost目录 执行bootstrap.bat命令 开始安装 b2.exe instal…

JavaScript经典教程(二)-- CSS基础部分

179&#xff1a;HTML基础部分&#xff08;元素分类、特性、特殊元素等&#xff09; — 补充 1、盒子模型 定义&#xff1a;一个元素在页面中所占的位置大小&#xff0c;叫盒子模型。 包含的样式&#xff1a;即影响元素大小的样式&#xff1a; width、height、margin、padding…

使用MyBatis实现关联查询

文章目录 一&#xff0c;查询需求&#xff08;一&#xff09;针对三张表关联查询&#xff08;二&#xff09;按班级编号查询班级信息&#xff08;三&#xff09;查询全部班级信息 二&#xff0c;创建数据库表&#xff08;一&#xff09;创建教师表&#xff08;二&#xff09;创…

云计算中的自动化运维技术及其实践

引言 随着云计算技术的快速发展&#xff0c;云计算成为了企业数据中心的新生态&#xff0c;提供了更加灵活、高效、安全的 IT 基础设施和应用服务&#xff0c;让企业能够更加专注于业务创新和变革。但是&#xff0c;云计算的快速发展也带来了新的安全挑战&#xff0c;尤其是在…

达摩院开源工业级说话人识别模型CAM++

近日&#xff0c;达摩院正式向公众开源工业级说话人识别通用模型CAM&#xff0c;兼顾准确率和计算效率&#xff0c;训练labels类别达20万&#xff0c;每类含20&#xff5e;200条梅尔频谱特征。当前该模型已上线Modelscope魔搭社区&#xff0c;后续将陆续开源针对各场景优化的工…

TCP协议三次握手过程分析

TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议&#xff0c;提供可靠的连接服务&#xff0c;采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结…

Vue3技术4之watch监视属性、watch时value问题

Vue3技术4 watch监视属性watch监视ref定义的数据情况一&#xff1a;监视ref所定义的一个响应式数据App.vueDemo.vue 情况二&#xff1a;监视ref所定义的多个响应式数据App.vueDemo.vue 添加immediate属性Demo.vue watch监视reactive定义的数据情况一&#xff1a;监视reactive所…

直播带货冲击实体生意,杭州四季青打响禁止直播带货第一枪

最近&#xff0c;“杭州四季青部分市场禁止直播”的话题冲上热搜。 身处“直播电商之城”杭州的“中国服装行业第一街”杭州四季青的部分市场&#xff0c;打响了“驱逐直播第一枪”&#xff01; 杭州四季青部分市场内为什么要明令禁止直播&#xff0c;直播卖货对实体商户带来了…

华锐3d虚拟数字人提供哪些智能化服务?

虚拟数字人的诞生是互联网时代的产物&#xff0c;它的出现为数字化经济提供了全新解决方案。数字化技术和网络使人类得以进入以“智能机器数据算法”为主线的新生态之中。 广州华锐互动作为专业的AI虚拟数字人开发商&#xff0c;拥有成熟的技术团队和一流的解决方案&#xff0…

零售数据分析操作篇15:用总聚合做销售分析

上一讲讲了内存计算筛选&#xff0c;又可称之为自定义计算成员筛选&#xff0c;即当某列是通过自定义计算成员得到的时候&#xff0c;还要想利用其作为筛选条件&#xff0c;就需要用到自定义计算成员筛选功能。 上一讲还给大家出了道作业&#xff0c;就是&#xff1a;想知道哪…

RHCE-DNS服务器

主机名称解析服务器配置 要求&#xff1a; 1、建立DNS服务器&#xff0c;负责解析的域为openedu.com&#xff1b; 建立DNS首先需要在服务器端配置主配置文件&#xff1a; &#xff08;1&#xff09;临时关闭防火墙和selinux&#xff1a;systemctl stop firewalld&#xff1b;…

靶机精讲之HackademicRTB1

主机发现 nmap扫描 端口扫描 只有80端口开放 UDP扫描 web渗透 服务扫描 脚本扫描 DOS攻击漏洞 枚举漏洞 查看web端 进行目录爆破 点击 点击后发现地址结构像有目录爆破 接上面枚举漏洞 复制那枚举目录到web 接目录爆破 apeache服务器 查看内容管理系统是否是自建的 在库搜索…

【rustdesk】rust入门及 windows尝试编译

rustup 微软建议用vs code开发 下载了64位的版本: vs code 插件 rust-analyer 介绍Better TOML,用于更好的展示.toml文件Error Lens, 更好的获得错误展示 One Dark Pro, 非常好看的Vscode主题 CodeLLDB, debugger程序 安装

2023年工商管理在职研究生择校、择专业指南

工商管理在职研究生是许多管理岗位从业者提升职业素质、竞争力的重要途径。 工商管理在职研究生学习的内容更加专业、深入&#xff0c;涵盖的领域更加广泛&#xff0c;通过学习&#xff0c;可以提高专业素养&#xff0c;掌握更深入的理论和实务知识&#xff0c;拓宽人脉&#…

爆爆爆!!Deep Mind与Google Brain合并,成立 Google DeepMind 新部门

图&#xff5c;2010-2023&#xff0c;从 DeepMind 到 Google DeepMind&#xff0c;再到 DeepMind&#xff0c;再到 Google DeepMind 来源: 学术头条 微信号&#xff1a;SciTouTiao 或许是深深感受到了来自 OpenAI 与微软一起给到的巨大压力&#xff0c;以及加速实现通用人工智…

基于 VITA57.4 标准的 8 路 500MSPS/1GSPS/1.25GSPS 采样率 14 位 AD 采集 FMC 子卡模块

板卡概述 FMC148 是一款基于 VITA57.4 标准的 JESD204B 接口 FMC 子卡模块&#xff0c;该模块可以实现 8 路 14-bit、500MSPS/1GSPS/1.25GSPS ADC 采集功能。该板卡 ADC 器件采用 ADI 公司的 AD9680 芯片,全 功率-3dB 模拟输入带宽可达 2GHz。该 ADC 与 FPGA 的主机接口通 …