当前位置:网站首页>适配器模式
适配器模式
2022-08-04 16:39:00 【l_ethan】
目录
简介
适配器是一种结构型设计模式,它能使接口不兼容的对象能够相互合作。
适配器可以转换不同格式的数据,有助于采用不同接口的对象之间的合作
运作方式
1.适配器实现与其中一个现有对象兼容的接口
2.现有对象可以使用该接口安全地调用适配器方法。
3.适配器方法被调用后将另一个对象兼容的格式和顺序将请求传递给该对象
优点:
1.单一职责原则你可以将接口或数据转换代码从程序主要业务逻辑中分离
2.开闭原则,只要客户端代码通过客户端接口与适配器进行交互,就能在不修改现有客户端代码的情况下在程序中添加新类型的适配器
缺点:
代码整体复杂度增加,因为需要新增一系列接口和类。有时直接更改服务类使其与其他代码兼容更简单
结构
适配器实现了其中一个对象的几口,并对另一个对象进行封装。
1.客户端(client)是包含当前程序业务逻辑的类
2.客户端接口(Client Interface)描述了其他类与客户端代码合作时必须遵循的协议
3.服务(Service)中有一些功能类(通常来自第三方或遗留系统)。客户端与其接口不兼容,因此无法直接调用其功能。
4.适配器(Adapter)是一个可以同时与客户端和服务交互的类:它在实现客户端接口的同时封装了服务对象。适配器接受客户端通过适配器接口发起的调用,并将其转化为为适用于被封装服务对象的调用。
5.客户端代码只需通过接口与适配器交互即可,无需与具体的适配器耦合。因此,可以向程序中添加新类型的适配器而无需修改已有代码。这在服务类的接口被更改或替换时很有用:无需修改客户端代码就可以创建新的适配器类。
类适配器
这一实现使用了继承机制:适配器同时继承两个对象的接口。这种方式仅能在支持多重继承的编程中语言实现如C++。
类适配器不需要封装任何对象,它同时继承了客户端和服务的行为。适配功能在重写的方法中完成。最后生成的适配器可替代已有的客户端进行使用。
案例
#include <iostream>
#include <string>
using namespace std;
//圆钉:客户端接口
class RoundPeg {
public:
RoundPeg(){}
virtual int get_radius() = 0;
};
//方钉:适配者类,即和客户端不兼容的类
class SquarePeg {
public:
explicit SquarePeg(int w) :width(w) {
}
int get_width() {
return width;
}
private:
int width;
};
//方钉适配器:该适配器能让客户端将方钉放入圆孔中
class SquarePegAdapter :public RoundPeg {
public:
explicit SquarePegAdapter(SquarePeg *sp):square_peg(sp){}
int get_radius() override {
return square_peg->get_width() * sqrt(2) / 2;
}
private:
SquarePeg* square_peg;
};
//圆孔:客户端类
class RoundHole {
public:
explicit RoundHole(int r) :radius(r) {
}
int get_radius() {
return radius;
}
bool isFit(RoundPeg* rp) {
return radius >= rp->get_radius();
}
private:
int radius;
};
int main()
{
RoundHole* hole = new RoundHole(10);
//半径分别为5和20大小方钉+它们的适配器
SquarePeg* small_square_peg = new SquarePeg(5);
SquarePeg* large_square_peg = new SquarePeg(20);
SquarePegAdapter* small_square_peg_adapter = new SquarePegAdapter(small_square_peg);
SquarePegAdapter* large_square_peg_adapter = new SquarePegAdapter(large_square_peg);
if (hole->isFit(small_square_peg_adapter)) {
cout << "small square fits the hole" << endl;
}
else {
cout << "small square don't fits the hole" << endl;
}
if (hole->isFit(large_square_peg_adapter)) {
cout << "large square fits the hole" << endl;
}
else {
cout << "large square don't fits the hole" << endl;
}
return 0;
}
边栏推荐
- DMS 有接口获取每个实例下的数据库列表吗
- MetaAI科学家解读最新模型:200+语言互译,扩充千倍翻译数据,全球元宇宙用户自由交流
- Steady Development | Data and Insights on Mobile Game Players in Western Europe
- Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World。
- seaborn
- Mobile BesTV_R3300-L_S905L_8189_wire brush firmware package
- "Distributed cloud best practices" BBS, on August 11, shenzhen
- 屏幕分辨率兼容性
- 码蹄集 - MT2142 - 万民堂大厨
- Tomato assistant downloading tomatoes
猜你喜欢
葫芦娃解析
麒麟信安石勇博士荣获openEuler社区年度开源贡献之星
平稳发展 | 西欧地区手游玩家的数据和洞察
JVM Tuning-GC Fundamentals and Tuning Key Analysis
GraphQL 入门与实践
移动CM101s_MV100_EMMC_M8233_强刷后全分区线刷固件包
"Distributed cloud best practices" BBS, on August 11, shenzhen
服装店如何利用好积分?
备战9月,美团50道软件测试经典面试题及答案汇总
【Pick-in】Advertising-information flow cross-domain CTR estimation (to be updated)
随机推荐
Minecraft 我的世界 .minecraft下的各个文件夹的用处
移动CM101s_MV100_EMMC_M8233_强刷后全分区线刷固件包
浙江数码代工M301H 免拆通刷_卡刷固件包(语音OK)
备战9月,美团50道软件测试经典面试题及答案汇总
Does DMS have an interface to get the list of databases under each instance?
代码重构:面向单元测试
HyperBDR云容灾深度解析一:云原生跨平台容灾,让数据流转更灵活
\/ PN的综合实验
《分布式云最佳实践》分论坛,8月11日深圳见
码蹄集 - MT2094 - 回文之时:第4组数据错误
广东湛江海关破获3起走私冻海产品案 查证案值约1亿元
Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World。
SAP 电商云 Spartacus UI 页面布局的设计原理
GraphQL 入门与实践
咪咕MGV2000KL南传_S905L3B_MT7668线刷固件包
码蹄集 - MT2142 - 万民堂大厨
拼多多详情API接口深度解读
LeetCode·每日一题·1403.非递增顺序的最小子序列·贪心
泰坦尼克号沉船数据之美——起于悲剧,止于浪漫
勒索软件的原理