设计模式之适配器模式(C++)
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之适配器模式(C++)相关的知识,希望对你有一定的参考价值。
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
一、适配器模式是什么?
适配器模式是一种结构型的软件设计模式,也称包装模式,即将相对复杂的功能(可能用到多个类)封装起来,提供一个使用者想要的接口,使用者只需要调用接口,不需要知道接口里封装的内容是如何实现的。
我个人工作中比较常用的设计模式就是适配器模式了,因为我司设计的算法库往往需要涵盖几十甚至更多的功能类,各个类组合起来就能实现一些工程上的技术,若不对其进行组合封装,则调用算法库的软件工程师(不具备专业技术背景)就不知道如何使用了。而通过适配器模式可以将复杂的功能封装起来,只提供一个接口给软件部门,软件工程师只需要按照算法给定的要求调用接口即可。
适配器模式的优点:
- 良好封装性。接口内的内容对使用者而言是透明的,即看不见,这确保了内部功能具备较好的封装性,不易被改动。
- 解耦。不匹配的两方在适配器的作用下可以做到解耦,不需要修改任何一方原有代码逻辑。
- 良好复用性。适配的两方不需要做任何修改,业务的实现可以通过适配器来完成,不同的业务可以使用不同的适配器。
- 良好扩展性。若要增加业务场景,只需要增加适配器类,来满足业务即可。
适配器模式的缺点:
- 不利于维护。因为业务的实现基于适配器完成,适配器中代码的复杂程度会越来越高,不熟悉业务或者底层逻辑的人难以短时间内接手维护。
- 系统结构易混乱。当业务量快速增加时,适配器类的数量也会快速增加,没有良好的系统架构布局,最终会使得整个系统臃肿且危险。
适配器模式一般分为类适配器模式和对象适配器模式。
1)类适配器模式:适配器类通过继承适配者类(多重继承),达到适配目的,部分语言可能不支持多重继承(如C#)。
2)对象适配器模式:适配器类中存放适配者类的实例对象,调用它来达到适配目的,该模式较常用。
二、类适配器模式
2.1 结构图
客户端即Main主函数,接口类给客户调用,适配者类是要被重新封装的功能类。在类适配器模式中,适配器类继承于接口类和适配者类,并在类中进行相关封装操作,使接口兼容。
2.2 代码示例
场景描述:我准备调用一款巴斯勒相机进行相关工作,但是其SDK的接口与我希望的接口不太一样,为此我设计了一个适配器类,对巴斯勒第三方库进行再次封装,以使接口符合我的要求。
//BaslerCamera.h
/****************************************************/
#pragma once
#include <iostream>
using namespace std;
// 巴斯勒相机类(适配者)
class BaslerCamera
public:
// 打开相机
void openBaslerCamera()
cout << "巴斯勒相机:打开相机。" << endl;
// 关闭相机
void closeBaslerCamera()
cout << "巴斯勒相机:关闭相机。" << endl;
// 打开曝光设置
void openExposureSettings()
cout << "巴斯勒相机:打开曝光设置。" << endl;
// 更改相机帧率
void changeCameraFrame()
cout << "巴斯勒相机:更改相机帧率。" << endl;
;
//Camera.h
/****************************************************/
#pragma once
#include <iostream>
#include "BaslerCamera.h"
using namespace std;
// 相机接口类
class Camera
public:
// 构造函数
Camera() ;
// 析构函数
virtual ~Camera() ;
// 打开相机
virtual void openCamera() = 0;
// 关闭相机
virtual void closeCamera() = 0;
// 配置属性
virtual void setConfig() = 0;
;
// 相机适配器类
class CameraAdapter :public Camera, public BaslerCamera
public:
// 打开相机
virtual void openCamera()
openBaslerCamera();
// 关闭相机
virtual void closeCamera()
closeBaslerCamera();
// 配置属性
virtual void setConfig()
// 打开曝光设置
openExposureSettings();
// 更改相机帧率
changeCameraFrame();
;
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Camera.h"
using namespace std;
int main()
Camera *m_camera = new CameraAdapter();
// 打开相机
m_camera->openCamera();
// 配置相机
m_camera->setConfig();
// 关闭相机
m_camera->closeCamera();
delete m_camera;
return 0;
程序结果如下。
在上述示例中,我们可以看到,巴斯勒相机的相关功能被我进行了再次封装,我只需要通过继承了接口类的适配器类,调用相关的接口即可完成我要的功能,至于接口中如何调用巴斯勒的库,那就是接口开发者的工作了。
三、对象适配器模式
3.1 结构图
对象适配器模式和类适配器模式相比,更适合大型项目的开发。在该模式中,适配器只需要继承接口类即可,而适配者以实例对象的形式存放在适配器类中,适配器通过调用对象的相关功能,同样可以达到封装效果。
3.2 代码示例
场景描述:与类适配器模式一致。
//Camera.h
/****************************************************/
#pragma once
#include <iostream>
#include "BaslerCamera.h"
using namespace std;
// 相机接口类
class Camera
public:
// 构造函数
Camera() ;
// 析构函数
virtual ~Camera() ;
// 打开相机
virtual void openCamera() = 0;
// 关闭相机
virtual void closeCamera() = 0;
// 配置属性
virtual void setConfig() = 0;
;
// 相机适配器类
class CameraAdapter :public Camera
public:
// 构造函数
CameraAdapter()
m_baslerCamera = new BaslerCamera();
// 析构函数
virtual ~CameraAdapter()
if (m_baslerCamera != nullptr)
delete m_baslerCamera;
m_baslerCamera = nullptr;
// 打开相机
virtual void openCamera()
m_baslerCamera->openBaslerCamera();
// 关闭相机
virtual void closeCamera()
m_baslerCamera->closeBaslerCamera();
// 配置属性
virtual void setConfig()
// 打开曝光设置
m_baslerCamera->openExposureSettings();
// 更改相机帧率
m_baslerCamera->changeCameraFrame();
private:
BaslerCamera *m_baslerCamera; // 适配者类实例
;
适配器类做了改变,类中增加了一个适配者类的实例对象,调用的结果同类适配器模式一致,就不再展示了。
四、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对适配器模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解适配器模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
以上是关于设计模式之适配器模式(C++)的主要内容,如果未能解决你的问题,请参考以下文章