《设计模式的艺术》笔记 - 适配器模式

介绍

        适配器模式将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。

实现

对象适配器模式

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Target {  // 目标类
public:virtual void request() = 0;
};class Adaptee {     // 适配者类
public:void specificRequest();
};class Adapter : public Target { // 适配器类
public:Adapter(Adaptee *adaptee);void request() override;private:Adaptee *m_adaptee;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Adapter::Adapter(Adaptee *adaptee) {m_adaptee = adaptee;
}void Adapter::request() {if (m_adaptee) {m_adaptee->specificRequest();}
}void Adaptee::specificRequest() {std::cout << "Adaptee被适配" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Adaptee *adaptee = new Adaptee;Target *target = new Adapter(adaptee);target->request();delete target;delete adaptee;return 0;
}

类适配器模式

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Target {  // 目标类
public:virtual void request() = 0;
};class Adaptee {     // 适配者类
public:void specificRequest();
};class Adapter : public Target, public Adaptee { // 适配器类
public:void request() override;};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"void Adapter::request() {specificRequest();
}void Adaptee::specificRequest() {std::cout << "Adaptee被适配" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Target *target = new Adapter();target->request();delete target;return 0;
}

双向适配器

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Target {  // 目标类
public:void request();
};class Adaptee {     // 适配者类
public:void specificRequest();
};class Adapter { // 适配器类
public:Adapter(Target *target);Adapter(Adaptee *adaptee);void request();void specificRequest();private:Target *m_target;Adaptee *m_adaptee;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"void Target::request() {std::cout << "Target被适配" << std::endl;
}Adapter::Adapter(Target *target) {m_target = target;
}Adapter::Adapter(Adaptee *adaptee) {m_adaptee = adaptee;
}void Adapter::request() {if (m_adaptee) {m_adaptee->specificRequest();}
}void Adapter::specificRequest() {if (m_target) {m_target->request();}
}void Adaptee::specificRequest() {std::cout << "Adaptee被适配" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Target *target = new Target();Adaptee *adaptee = new Adaptee();Adapter *adapter = new Adapter(target);adapter->specificRequest();delete adapter;adapter = new Adapter(adaptee);adapter->request();delete adapter;delete adaptee;delete target;return 0;
}

缺省适配器模式

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class ServiceInterface {    // 适配者接口
public:virtual void request() = 0;virtual void request2() = 0;virtual void request3() = 0;
};class AbstractService : public ServiceInterface {     // 缺省适配器类
public:virtual void request() override;virtual void request2() override;virtual void request3() override;
};class Adaptee {     // 适配者类
public:void specificRequest();
};class Adapter : public AbstractService { // 具体适配器类
public:Adapter(Adaptee *adaptee);void request() override;private:Adaptee *m_adaptee;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Adapter::Adapter(Adaptee *adaptee) {m_adaptee = adaptee;
}void Adapter::request() {if (m_adaptee) {m_adaptee->specificRequest();}
}void Adaptee::specificRequest() {std::cout << "Adaptee被适配" << std::endl;
}void AbstractService::request() {std::cout << "缺省函数request" << std::endl;
}void AbstractService::request2() {std::cout << "缺省函数request2" << std::endl;
}void AbstractService::request3() {std::cout << "缺省函数request3" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Adaptee *adaptee = new Adaptee();Adapter *adapter = new Adapter(adaptee);adapter->request();adapter->request2();adapter->request3();delete adapter;delete adaptee;return 0;
}

总结

优点

        1. 将目标类和适配者类解耦。通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。

        2. 增加了类的透明性和复用性。将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者类的复用性,同一个适配者类可以在多个不同的系统中复用。

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

缺点

        1. 对于Java、C#等不支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配者。

        2. 适配者类不能为最终类,例如在Java中不能为final类,C#中不能为sealed类。

        3. 在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定的局限性。

适用场景

        1. 系统需要使用一些现有的类,而这些类的接口(例如方法名)不符合系统的需要,甚至没有这些类的源代码。

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

练习

对象适配器模式

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Encryption {  // 目标类
public:virtual std::string encrypt(std::string data) = 0;
};class ThirdLib {     // 适配者类
public:std::string specificEncrypt(std::string data);std::string specificDecrypt(std::string data);
};class AdapterEncyption : public Encryption {    // 适配器类
public:AdapterEncyption(ThirdLib *thirdLib);~AdapterEncyption();std::string encrypt(std::string data) override;private:ThirdLib *m_thirdLib;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"AdapterEncyption::AdapterEncyption(ThirdLib *thirdLib) {m_thirdLib = thirdLib;
}AdapterEncyption::~AdapterEncyption() {if (m_thirdLib) {delete m_thirdLib;}
}std::string AdapterEncyption::encrypt(std::string data) {if (m_thirdLib) {return m_thirdLib->specificEncrypt(data);}return data;
}std::string ThirdLib::specificEncrypt(std::string data) {return "加密后的" + data;
}std::string ThirdLib::specificDecrypt(std::string data) {return "解密后的" + data;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {ThirdLib *thirdLib = new ThirdLib();Encryption *encryption = new AdapterEncyption(thirdLib);std::string data = encryption->encrypt("口令");std::cout << data << std::endl;data = encryption->encrypt("邮箱");std::cout << data << std::endl;return 0;
}

类适配器模式

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Encryption {  // 目标类
public:virtual std::string encrypt(std::string data) = 0;
};class ThirdLib {     // 适配者类
public:std::string specificEncrypt(std::string data);std::string specificDecrypt(std::string data);
};class AdapterEncyption : public Encryption, public ThirdLib {    // 适配器类
public:AdapterEncyption();~AdapterEncyption();std::string encrypt(std::string data) override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"AdapterEncyption::AdapterEncyption() {}AdapterEncyption::~AdapterEncyption() {}std::string AdapterEncyption::encrypt(std::string data) {return specificEncrypt(data);
}std::string ThirdLib::specificEncrypt(std::string data) {return "加密后的" + data;
}std::string ThirdLib::specificDecrypt(std::string data) {return "解密后的" + data;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Encryption *encryption = new AdapterEncyption();std::string data = encryption->encrypt("口令");std::cout << data << std::endl;data = encryption->encrypt("邮箱");std::cout << data << std::endl;delete encryption;return 0;
}

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

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

相关文章

《Python数据分析技术栈》第03章 03 可视化各级数据(Visualizing various levels of data)

03 可视化各级数据&#xff08;Visualizing various levels of data&#xff09; 《Python数据分析技术栈》第03章 03 可视化各级数据&#xff08;Visualizing various levels of data&#xff09; Whenever you need to analyze data, first understand if the data is stru…

二叉树的直径(LeetCode 543)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路参考文献 1.问题描述 给你一棵二叉树的根节点&#xff0c;返回该树的直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的长度由它们之间边数…

QT上位机开发(Web API联调)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在工厂里面,一条流水线,或者说一条生产线,常常是由很多家供应商的产品组合在一起,共同完成商品的生产和制造的。这里面有不同供应商的软件,也有集成商的软件,甚至有生产厂家i…

使用一份红黑树封装set和map

set&&map set/map简介set特性map特性红黑树的接口set的封装map的封装 总结 set/map简介 我们所熟知的vector、list、deque被称为序列是容器&#xff1b;set和map是c中的关联式容器&#xff0c;他们都是用来储存数据的。 只不过关联式容器里面存储的不是单个元素&#…

CentOS Linux操作系统源码安装最新Redis版本,使用JSON数据类型踩入新坑

最近有空查阅了redis官网&#xff0c;发现redis数据类型不止Strings、Lists、Sets、Hashes、Sorted sets&#xff0c;还多了几种&#xff0c;决定先试用下JSON数据类型 1、安装Redis软件 JSON数据类型&#xff0c;对Redis版本有要求&#xff0c;需要大于4.0版本。下图是华为云…

开源项目介绍

浙大高飞课题组 微分平坦 微分平坦的思想是&#xff1a;一个全维度的状态空间可以被一组低维的精心挑选的输出平坦空间&#xff08;flat-output space&#xff09;的变量及其导数的代数组合的方式所表示。由此&#xff0c;轨迹规划就可以在这组精心挑选的变量的空间所进行。 …

【C++提高编程(二)】

一、STL初识 1.1、STL的诞生 长久以来&#xff0c;软件界一直希望建立一种可重复利用的东西 C的面向对象和泛型编程思想&#xff0c;目的就是复用性的提升 大多情况下&#xff0c;数据结构和算法都未能有一套标准,导致被迫从事大量重复工作 为了建立数据结构和算法的一套标…

一文详解 Berachain 测试网:全面介绍与教程,bitget wallet教程

什么是Berachain&#xff1f; Berachain&#xff08;web3.bitget.com/zh-CN/assets/berachain-wallet&#xff09;是一种尖端区块链技术&#xff0c;使用 Cosmos SDK 构建的 Layer-1&#xff0c;兼容以太坊虚拟机&#xff08;EVM&#xff09;。它基于一种独特的概念&#xff0c…

【AI】人工智能和图像编码(2)

传统图像编解码与智能图像编解码&#xff0c;都是要编码和解码&#xff0c;但还是有一些区别的。 相关相同点和要点描述如下&#xff1a; 一、区别 1.1 技术原理 传统图像编解码&#xff1a;主要依赖于固定的算法和标准&#xff0c;如JPEG、MPEG等&#xff0c;进行图像的压…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--机器人相关、强化学习

专属领域论文订阅 VX 扫吗关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航具身智能&#xff0c;机器人强化学习开放词汇&#xff0c;检测分割 [晓理紫…

LeetCode、2542. 最大子序列的分数【中等,排序+小顶堆】

文章目录 前言LeetCode、2542. 最大子序列的分数【中等&#xff0c;排序小顶堆】题目及类型思路及代码实现 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领…

2024最新AWVS/Acunetix Premium v24.1.24高级版漏洞扫描器Windows/Linux下载

前言 Acunetix Premium 是一种 Web 应用程序安全解决方案&#xff0c;用于管理多个网站、Web 应用程序和 API 的安全。集成功能允许您自动化 DevOps 和问题管理基础架构。 Acunetix Premium&#xff1a;全面的 Web 应用程序安全解决方案 Web 应用程序对于企业和组织与客户、合作…

多选下拉框(select 下拉多选)

https://www.cnblogs.com/sherryweb/p/11057746.html 多选下拉框&#xff08;select 下拉多选&#xff09; 方法一&#xff1a;使用multiple-select.js和multiple-select .css实现 HTML代码&#xff1a; <select idcheckedLevel style"width:120px;height:28px;"…

算法练习-替换数字(思路+流程图+代码)

难度参考 难度&#xff1a;简单 分类&#xff1a;字符串 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。以下内容均为个人笔记&#xff0c;旨在督促自己认真学习。 题目 给定一个字符串S,它包含小写字母和数字字符&#xff0…

EXCEL VBA获取幸运数字号码

EXCELVBA获取幸运数字号码 以下就是VBA幸运号码产生的程序&#xff0c;复制粘贴到VBA代码框即可运行 Option Base 1 Sub 幸运号码()Dim n As Integer, i As Integer, j As IntegerDim l() As Integern Application.InputBox("请输入需要产生幸运号码的数量&#xff1a;…

设备巡检系统开发及部署

**凡尔码设备巡检系统**是一种低代码模块搭建设备管理系统平台&#xff1b;用户可通过平台开发好的组件像搭积木一般灵活搭建设备管理平台和无纸化应用场景。凡尔码平台功能组件&#xff1a;二维码管理、表单管理、流程管理、计划管理、权限管理、隐患管理、区域管理、记录管理…

Pytorch数据操作

数据操作 # 导入PyTorch import torch [张量表示一个由数值组成的数组&#xff0c;这个数组可能有多个维度]。 具有一个轴的张量对应数学上的向量&#xff08; &#xff09;&#xff1b; 具有两个轴的张量对应数学上的矩阵&#xff08;matrix&#xff09;&#xff1b; 具有两…

docker下安装rabbitmq

1.查询rabbitmq的镜像 docker search rabbitmq 2.安装镜像 如果需要安装其他版本在rabbitmq后面跟上版本号即可 docker pull rabbitmq:3.7.7-management docker pull rabbitmq:版本号 -management 直接安装最新的 docker pull rabbitmq 3.启动容器 docker run -dit --name rab…

数据结构之二叉树的性质与存储结构

数据结构之二叉树的性质与存储结构 1、二叉树的性质2、二叉树的存储结构 数据结构是程序设计的重要基础&#xff0c;它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发&#xff0c;分析和研究计算机加工的数据的特性&#xff0c;…

【趣味题-03】20240120猴子吃桃( 从大到小insert ,列表元素互减)

背景需求&#xff1a; 猴子摘桃的题目 解决&#xff1a; 猴子吃桃 倍数问题 作者&#xff1a;阿夏 时间&#xff1a;2024年1月20日猴子吃桃问题-1 猴子第一天摘了许多桃子&#xff0c;第一天吃了一半&#xff0c;&#xff1b;第二天又吃了一半&#xff0c; 后面每天都是这样吃…