C++之装饰器适配器模式

目录

一、装饰器模式

模式思想

模式简介

模式优点

模式缺点

代码实现

情景模拟

代码实现

运行结果

二、适配器模式

模式简介

介绍

优点

缺点

代码实现

情景模拟


一、装饰器模式

模式思想

模式简介

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。
这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

意图:

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
何时使用:
在不想增加很多子类的情况下扩展类。
如何解决:
将具体功能职责划分,同时继承装饰器模式

模式优点

装饰类被装饰类可以独立发展,不会相互耦合,装饰器模式是继承的一个替代模式,装饰器模式可以动态地扩展实现一个类的功能。

模式缺点

多层装饰比较复杂。

代码实现

情景模拟

我们还是拿汽车来举例子吧。
现在的汽车越来越智能化了,什么定速巡航自动刹车车道偏离等功能都逐渐进入我们的生活,为我们带来了更为便利的出行。

假设上述提到的定速巡航自动刹车车道偏离三个功能就是我们想要为汽车装饰的功能,汽车默认的功能配置有:基本配置

得到具体的汽车(宝马奥迪奔驰)后,我们可以选择性地增加装饰功能。

代码实现

具体实现如下:


//抽象基类
class Car
{
public:virtual void show() = 0;
};//三个实体的基类
class Bmw : public Car
{
public:void show(){cout << "这是一辆宝马汽车,配置有:基本配置";}
};
class Audi : public Car
{
public:void show(){cout << "这是一辆奥迪汽车,配置有:基本配置";}
};
class Benz : public Car
{
public:void show(){cout << "这是一辆奔驰汽车,配置有:基本配置";}
};//装饰器的基类
class CarDecorator : public Car
{
public:CarDecorator(Car* p):pCar(p){}
private:Car* pCar;
};//装饰器1 :定速巡航
class ConcreateDecorator1 : public Car
{
public:ConcreateDecorator1(Car* p):pCar(p){}void show(){pCar->show();cout << "定速巡航功能,";}
private:Car* pCar;
};
//装饰器2 :自动刹车
class ConcreateDecorator2 : public Car
{
public:ConcreateDecorator2(Car* p) :pCar(p){}void show(){pCar->show();cout << "自动刹车";}
private:Car* pCar;
};
//装饰器3 :车道偏离
class ConcreateDecorator3 : public Car
{
public:ConcreateDecorator3(Car* p) :pCar(p){}void show(){pCar->show();cout << "车道偏离";}
private:Car* pCar;
};

运行结果

接着我们可以使用如下代码:

void main()
{Car* p1 = new ConcreateDecorator1(new Bmw());p1 = new ConcreateDecorator2(p1);p1->show();cout << endl;Car* p2 = new ConcreateDecorator2(new Audi());p2->show();cout << endl;Car* p3 = new ConcreateDecorator3(new Benz());p3->show();cout << endl;
}

可以看到,我们在运行代码中:
宝马汽车增加了Decorator01(定速巡航)Decorator02(自动刹车)Decorator03(车道偏离)的配置;
奥迪汽车增加了Decorator02(自动刹车配置;
奔驰汽车增加了Decorator03(车道偏离)配置。

二、适配器模式

模式简介

介绍

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。

这种类型的设计模式属于结构型模式

意图:
将一个类的接口转换成为客户希望的另一个接口
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
主要解决:
主要解决在软件系统中,常常要将一些“现存的对象”放到新环境中,而新环境的接口是现有对象不能满足的。

优点

  1. 可以让任何两个没有关联的类一起工作;
  2. 提高了类的复用;
  3. 增加了类的透明度;
  4. 灵活性好。

缺点

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

代码实现

情景模拟

同样的,我们来模拟这么一个场景:

我们要安装一个投影仪:能够将电脑上的画面投影出来,对于投影仪来说,常见的接口有:VGA、HTMI接口,但是对于不同的电脑,接口一定是固定的,一个电脑必然只有一种接口,我们往往会出现接口不适配的情况。

我们就来模拟不兼容的两个接口:VGAHDMI之间,如何通过一个适配器adapter连接在一起工作的。

当我们的电脑是VGA接口的时候,我们很自然能连接VGA的投影仪,但是当我们想要去连接HTMI的投影仪时,问题必然就出现了。

 我们可以添加一个适配器类:

/*
适配器模式:让不兼容的接口可以在一起工作VGA接口的电脑,投影仪也是VGA接口
*///VGA接口类
class VGA
{
public:virtual void play() = 0;
};//表示支持VGA接口的投影仪
class TV1 :public VGA
{
public:void play(){cout << "通过VGA接口连接投影仪,进行视频播放 " << endl;}
};//实现一个电脑类(只支持VGA接口)
class Computer
{
public://由于电脑支持VGA接口,所以该方法的参数智能支持VGA即可的指针/引用void playVideo(VGA* pVGA){pVGA->play();}
};
/*
方法1:换一个支持HDMI接口的电脑,这个就叫代码重构
方法2:买一个转换头(适配器),能够把VGA信号转换成?HDMI信号,这个叫添加适配器类*///进了一批新的投影仪,但是新的投影仪都是只支持HDMI接口
//HDMI接口类
class HDMI
{
public:virtual void play() = 0;
};
//表示支持HDMI接口的投影仪
class TV2 :public HDMI
{
public:void play(){cout << "通过HTMI接口连接投影仪,进行视频播放 " << endl;}
};//由于电脑(VGA接口)和投影仪(HTMI接口)无法直接相连,所以需要添加适配器类
class VGATOHDMI :public VGA
{
public:VGATOHDMI(HDMI* p) :pHdmi(p){}void play()//该方法相当于就是转换头,做不同接口的信号转换{pHdmi->play();}
private:HDMI* pHdmi;
};

运行一下:

void main()
{Computer cc;cc.playVideo(new TV1());cc.playVideo(new VGATOHDMI(new TV2()));}

结果:

 

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

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

相关文章

Sentinel服务器容错简介

spring gateway 详解 服务容错高并发带来的问题服务雪崩效应常见容错方案常见的容错思路1、隔离2、超时3、限流4、熔断5、降级 常见的容错组件 SentinelSentinel 具有以下特征:Sentinel概念和功能相关概念1、资源2、规则 重要功能 服务容错 高并发带来的问题 在微服务架构中&…

深入理解Linux内核 PHY 驱动框架

目录 一、背景 二、硬件拓扑 三、概述 四、PHY控制器驱动 五、PHY驱动解析 1、相关结构体 2、网口和mdio总线设备树配置 3、MAC驱动和mdio控制器注册 4、PHY设备驱动 5、PHY 设备驱动注册和加载 6、以太网卡 PHY 和 MAC 的协作 7、网络操作命令解析 8、设备驱动与…

postman测试接口出现404

postman测试接口出现404 1.用postman调试接口的过程中&#xff0c;出现404的情况&#xff0c;但是接口明明已调到了&#xff0c;而且数据也已经存入数据库了&#xff0c;这让我感到很疑惑。看网上的解决办法检查了我的路径&#xff0c;提交方式、参数类型等都是正确的&#xf…

【实战】 六、用户体验优化 - 加载中和错误状态处理(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理1~234.用useAs…

加密劫持者攻击教育机构

我们的专家分析了2023年第一季度的当前网络威胁。研究表明&#xff0c;独特事件的数量增加&#xff0c;勒索软件活动激增&#xff0c;特别是针对学术和教育机构。我们记录了大量与就业有关的网络钓鱼邮件&#xff0c;出现了QR网络钓鱼和恶意广告的增加。 我们的研究表明&#…

计算机组成原理课程论文: Intel 80386/80486 的体系架构调研

摘要 本文以Intel 80386/80486体系架构为研究对象&#xff0c;详细介绍了该体系架构的基本概念、特点和优势&#xff0c;分析了其在不同领域的应用情况&#xff0c;并对其未来的发展做出一定的展望和评价。 首先&#xff0c;我们介绍了研究背景和目的&#xff0c;阐述了Intel 8…

windows安装docker

目录 安装docekr Desktop下载安装 解决WSL 问题启用适用于 Linux 的 Windows 子系统检查运行 WSL 2 的要求启用虚拟机功能下载 Linux 内核更新包将 WSL 2 设置为默认版本 运行-可视化界面 安装docekr Desktop 下载 下载地址 Install Docker Desktop on Windows | Docker Docum…

攻防世界-web-ics-05

题目描述: 其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统 题目链接点进去如下&#xff1a; 可以看到界面上有一个设备维护中心&#xff0c;点击设备维护中心&#xff0c;跳转到如下界面 再次点击&#xff0c;发现变成这样了 1. 思路分析 从已知信息来看&#xf…

算法与数据结构(一)--算法复杂性

一.算法复杂性的概念 算法的复杂性是指运行算法所需要的计算机资源的量。需要的时间资源的量称为时间复杂性&#xff0c;需要的空间资源的量称为空间复杂性。 这个量应该集中反映算法的效率&#xff0c;而从运行该算法的实际计算机中抽象出来。换句话说&#xff0c;这个量应该…

【算法集训之线性表篇】Day 08

文章目录 题目基本设计思想思路一思路二 代码实现效果 题目 已知一个整数数列A{a0,a1,a2,…,an-1}&#xff0c;其中0<ai<n(0<i<n)。若存在ap1ap2ap3…apmx且m>n/2(0<pk<n,1<k<m)&#xff0c;则成x为A的主元素。例如A{0,5,5,3,5,7,5,5}&#xff0c;…

【后端面经-架构】RabbitMQ简介

【后端面经-架构】RabbitMQ简介 1. MQ介绍2. RabbitMQ2.1 简介2.2 架构&#xff1a;组件解释2.3 特点2.4 优缺点 面试模拟参考资料 1. MQ介绍 MQ&#xff08;Message Queue&#xff09;用于在应用程序之间相互通信&#xff0c;在消息中发送数据进行通信&#xff0c;而不需要特…

【视觉SLAM入门】3. 相机模型,内外参,畸变推导

"瑾瑜匿瑕" 1. 相机模型和内参1.1 内参推导1.2 外参推导 2. 畸变2.1 径向畸变2.2 切向畸变 3. 深度信息3.1 算法测距3.2 物理测距 本节讨论围绕这个问题展开 机器人如何观测外部世界&#xff1f; \quad\large\textcolor{red}{机器人如何观测外部世界&#xff1f;} 机…