最常用的设计模式---适配器模式(C++实现)

适配器模式属于结构型的设计模式,它是结构型设计模式之首(用的最多的结构型设计模式)。

适配器设计模式也并不复杂,适配器它是主要作用是将一个类的接口转换成客户希望的另外一个接口这样使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式有两种:1.类的适配器 2.对象适配器,对象适配器更多一些。

(适配器模式和装饰模式很类似,下面一篇我们会学习装饰者模式,并分析他们之间的区别)


示例:比如你在网上买了一个手机,但是买家给你发回来了一个3接头的充电器,但是恰好你又没有3接头的插槽,只有2个接口的插槽,于是你很直然地便会想到去找你个3接口转两接口的转换器。简单的分析下这个转换器便是我们这里的适配器Adapter。三相插头便是我们要适配的Adaptee,两相插

类适配器

-----在我看来C++的类适配器的用多重继承实现,并提供适配后的接口。



这是你的三相插头

[cpp] view plain copy
  1. class ThreePhaseOutlet  
  2. {  
  3. public:  
  4.     void doThreePhasePlugin()  
  5.     {  
  6.         cout<<"三相插头强势插入!"<<endl;  
  7.     }  
  8. };  
这是你想要的两相插头

[cpp] view plain copy
  1. class TwoPhaseOutlet   
  2. {  
  3. public:  
  4.     virtual void doPlugin() = 0;  
  5. };  

然后你将需要找到一个转接头,将三相插头转换为“两相插头”

[cpp] view plain copy
  1. class OutletConvertor: public TwoPhaseOutlet,public ThreePhaseOutlet  
  2. {  
  3. public:  
  4.     void doPlugin()  
  5.     {  
  6.         doConvertor();  
  7.         doThreePhasePlugin();  
  8.     }     
  9.         void doConvertor()  
  10.     {  
  11.         cout<<"三相插头转为两厢插头!"<<endl;  
  12.     }  
  13. };  
现在你可以强势插入两相的插口了。

[cpp] view plain copy
  1. TwoPhaseOutlet* outlet = new OutletConvertor();  
  2. outlet->doPlugin();  

对象适配器模式-----对象适配器是将需要适配的对象进行包装然后提供适配后的接口。

对象适配器的 三相插口和转接头的代码和上面一致。只是整合步骤不一致

[cpp] view plain copy
  1. class OutletConvertor : public TwoPhaseOutlet  
  2. {  
  3. public:  
  4.     void doPlugin()  
  5.     {  
  6.         doConvertor();  
  7.         m_out.doThreePhasePlugin();  
  8.     }  
  9.     void doConvertor()  
  10.     {  
  11.         cout<<"三相插头转为两厢插头!"<<endl;  
  12.     }  
  13.     ThreePhaseOutlet m_out;  
  14. };  
对象适配器相比类适配器来说更加灵活,他可以选择性适配自己想适配的对象。例如我们下面把代码改成这样,你也许就会明白为什么我这样说:

[cpp] view plain copy
  1. class OutletConvertor : public TwoPhaseOutlet  
  2. {  
  3. public:  
  4.     OutletConvertor(ThreePhaseOutlet out)  
  5.     {  
  6.         m_out = out;  
  7.     }  
  8.     void doPlugin()  
  9.     {  
  10.         doConvertor();  
  11.         m_out.doThreePhasePlugin();  
  12.     }  
  13.     void doConvertor()  
  14.     {  
  15.         cout<<"三相插头转为两厢插头!"<<endl;  
  16.     }  
  17.     ThreePhaseOutlet m_out;  
  18. };  

我们在构造的时候将具体需要适配的适配对象传入,这样便可以根据传入不同的对象,从而对该对象进行适配。而类适配器却无法选择对象,他是对整个类进行适配。也就是把所有的三相插口全部转换为两相的,而不是针对某一个。


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

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

相关文章

c++简单线程池实现

线程池&#xff0c;简单来说就是有一堆已经创建好的线程&#xff08;最大数目一定&#xff09;&#xff0c;初始时他们都处于空闲状态&#xff0c;当有新的任务进来&#xff0c;从线程池中取出一个空闲的线程处理任务&#xff0c;然后当任务处理完成之后&#xff0c;该线程被重…

Linux 打印可变参数日志

实现了传输进去的字符串所在的文档&#xff0c;函数和行数显示功能。 实现了将传入的可变参数打印到日志功能。 #include<stdio.h> #include<stdarg.h> #include<string.h>const char * g_path "/home/exbot/wangqinghe/log.txt"; #define LOG(fm…

C++强化之路之线程池开发整体框架(二)

一.线程池开发框架 我所开发的线程池由以下几部分组成&#xff1a; 1.工作中的线程。也就是线程池中的线程&#xff0c;主要是执行分发来的task。 2.管理线程池的监督线程。这个线程的创建独立于线程池的创建&#xff0c;按照既定的管理方法进行管理线程池中的所有线程&#xf…

vfprintf()函数

函数声明&#xff1a;int vfprintf(FILE *stream, const char *format, va_list arg) 函数参数&#xff1a; stream—这是指向了FILE对象的指针&#xff0c;该FILE对象标识了流。 format—c语言字符串&#xff0c;包含了要被写入到流stream中的文本。它可以包含嵌入的format标签…

TCP粘包问题分析和解决(全)

TCP通信粘包问题分析和解决&#xff08;全&#xff09;在socket网络程序中&#xff0c;TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程&#xff0c;收发两端&#xff08;客户端和服务器端&#xff09;都要有成对的socket&#xff0c;因此&#xff0c;发送端为了将…

UML类图符号 各种关系说明以及举例

UML中描述对象和类之间相互关系的方式包括&#xff1a;依赖&#xff0c;关联&#xff0c;聚合&#xff0c;组合&#xff0c;泛化&#xff0c;实现等。表示关系的强弱&#xff1a;组合>聚合>关联>依赖 相互间关系 聚合是表明对象之间的整体与部分关系的关联&#xff0c…

ESP传输模式拆解包流程

一、 ESP简介ESP&#xff0c;封装安全载荷协议(Encapsulating SecurityPayloads)&#xff0c;是一种Ipsec协议&#xff0c;用于对IP协议在传输过程中进行数据完整性度量、来源认证、加密以及防回放攻击。可以单独使用&#xff0c;也可以和AH一起使用。在ESP头部之前的IPV4…

linux内核netfilter模块分析之:HOOKs点的注册及调用

1: 为什么要写这个东西?最近在找工作,之前netfilter 这一块的代码也认真地研究过&#xff0c;应该每个人都是这样的你懂 不一定你能很准确的表达出来。 故一定要化些时间把这相关的东西总结一下。 0&#xff1a;相关文档linux 下 nf_conntrack_tuple 跟踪记录 其中可以根据内…

网络抓包工具 wireshark 入门教程

Wireshark&#xff08;前称Ethereal&#xff09;是一个网络数据包分析软件。网络数据包分析软件的功能是截取网络数据包&#xff0c;并尽可能显示出最为详细的网络数据包数据。Wireshark使用WinPCAP作为接口&#xff0c;直接与网卡进行数据报文交换。网络管理员使用Wireshark来…

结构体中指针

结构体中带有指针的情况 #include<stdio.h>struct man {char *name;int age; };int main() {struct man m {"tom",20};printf("name %s, age %d\n",m.name,m.age);return 0; } 运行结果&#xff1a; exbotubuntu:~/wangqinghe/C/20190714$ gcc st…

python使用opencv提取视频中的每一帧、最后一帧,并存储成图片

提取视频每一帧存储图片 最近在搞视频检测问题&#xff0c;在用到将视频分帧保存为图片时&#xff0c;图片可以保存&#xff0c;但是会出现(-215:Assertion failed) !_img.empty() in function cv::imwrite问题而不能正常运行&#xff0c;在检查代码、检查路径等措施均无果后&…

线程间通信之eventfd

线程间通信之eventfd man手册中的解释&#xff1a; eventfd()创建了一个“eventfd对象”&#xff0c; 通过它能够实现用户态程序间(我觉得这里主要指线程而非进程)的等待/通知机制&#xff0c;以及内核态向用户态通知的机制&#xff08;未考证&#xff09;。 此对象包含了一个…

定时器timerfd

1.为什么要加入此定时器接口 linux2.6.25版本新增了timerfd这个供用户程序使用的定时接口&#xff0c;这个接口基于文件描述符&#xff0c;当超时事件发生时&#xff0c;该文件描述符就变为可读。我首次接触这个新特性是在muduo网络库的定时器里看到的&#xff0c;那么新增一个…

timerfd与epoll

linux timerfd系列函数总结 网上关于timerfd的文章很多&#xff0c;在这儿归纳总结一下方便以后使用&#xff0c;顺便贴出一个timerfd配合epoll使用的简单例子 一、timerfd系列函数 timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符&#xff0c;通过文…

linux僵尸进程产生的原因以及如何避免产生僵尸进程defunct

给进程设置僵尸状态的目的是维护子进程的信息&#xff0c;以便父进程在以后某个时间获取。这些信息包括子进程的进程ID、终止状态以及资源利用信息(CPU时间&#xff0c;内存使用量等等)。如果一个进程终止&#xff0c;而该进程有子进程处于僵尸状态&#xff0c;那么它的所有僵尸…

linux下僵尸进程(Defunct进程)的产生与避免

在测试基于 DirectFBGstreamer 的视频联播系统的一个 Demo 的时候&#xff0c;其中大量使用 system 调用的语句&#xff0c;例如在 menu 代码中的 system("./play") &#xff0c;而且多次执行&#xff0c;这种情况下&#xff0c;在 ps -ef 列表中出现了大量的 defunc…

读过的最好的epoll讲解

首先我们来定义流的概念&#xff0c;一个流可以是文件&#xff0c;socket&#xff0c;pipe等等可以进行I/O操作的内核对象。 不管是文件&#xff0c;还是套接字&#xff0c;还是管道&#xff0c;我们都可以把他们看作流。 之后我们来讨论I/O的操作&#xff0c;通过read&#xf…

C语言指针转换为intptr_t类型

C语言指针转换为intptr_t类型 1、前言 今天在看代码时&#xff0c;发现将之一个指针赋值给一个intptr_t类型的变量。由于之前没有见过intptr_t这样数据类型&#xff0c;凭感觉认为intptr_t是int类型的指针。感觉很奇怪&#xff0c;为何要将一个指针这样做呢&#xff1f;如是果…

北京加密机现场select问题

问题描述 北京项目通过调用我们提供的库libsigxt.a与加密机通信&#xff0c;c/s架构&#xff0c;客户端启用多个线程&#xff0c;每个线程流程有以下三步&#xff0c;连接加密机&#xff0c;签名&#xff0c;关闭链接。在正常运行一段时间后会出现不能连接加密机服务问题。 连…

处理SIGCHLD信号

在上一讲中&#xff0c;我们使用fork函数得到了一个简单的并发服务器。然而&#xff0c;这样的程序有一个问题&#xff0c;就是当子进程终止时&#xff0c;会向父进程发送一个SIGCHLD信号&#xff0c;父进程默认忽略&#xff0c;导致子进程变成一个僵尸进程。僵尸进程一定要处理…