【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】
【简介】什么是适配器模式
适配器模式Adapter 是⼀种结构型设计模式,它可以将⼀个类的接⼝转换成客户希望的另⼀个接⼝,主要⽬的是充当两个不同接⼝之间的桥梁,使得原本接⼝不兼容的类能够⼀起⼯作。
【基本结构】
适配器模式分为以下⼏个基本⻆⾊:
- ⽬标接⼝Target : 客户端希望使⽤的接⼝
- 适配器类Adapter : 实现客户端使⽤的⽬标接⼝,持有⼀个需要适配的类实例。
- 被适配者Adaptee : 需要被适配的类
(可以把适配器模式理解成拓展坞,起到转接的作⽤,原有的接⼝是USB,但是客户端需要使⽤type-c , 便使⽤拓展坞提供⼀个type-c 接⼝给客户端使⽤)
这样,客户端就可以使⽤⽬标接⼝,⽽不需要对原来的Adaptee 进⾏修改, Adapter 起到⼀个转接扩展的作⽤。
【应用场景】
在开发过程中,适配器模式往往扮演者“补救”和“扩展”的⻆⾊:
- 当使⽤⼀个已经存在的类,但是它的接⼝与你的代码不兼容时,可以使⽤适配器模式。
- 在系统扩展阶段需要增加新的类时,并且类的接⼝和系统现有的类不⼀致时,可以使⽤适配器模式。
· 使⽤适配器模式可以将客户端代码与具体的类解耦,客户端不需要知道被适配者的细节,客户端代码也不需要修改,这使得它具有良好的扩展性,但是这也势必导致系统变得更加复杂。
具体来说,适配器模式有着以下应⽤:
- 不同的项⽬和库可能使⽤不同的⽇志框架,不同的⽇志框架提供的API也不同,因此引⼊了适配器模式使得不同的API适配为统⼀接⼝。
- Spring MVC中, HandlerAdapter 接⼝是适配器模式的⼀种应⽤。它负责将处理器(Handler)适配到框架中,使得不同类型的处理器能够统⼀处理请求。
- 在.NET 中, DataAdapter ⽤于在数据源(如数据库)和 DataSet 之间建⽴适配器,将数据从数据源适配到 DataSet 中,以便在.NET应⽤程序中使⽤。
【编码部分】
1. 题目描述
小明购买了一台新电脑,该电脑使用 TypeC 接口,他已经有了一个USB接口的充电器和数据线,为了确保新电脑可以使用现有的USB接口充电器和数据线,他购买了一个TypeC到USB的扩展坞。请你使用适配器模式设计并实现这个扩展坞系统,确保小明的新电脑既可以通过扩展坞使用现有的USB接口充电线和数据线,也可以使用TypeC接口充电。
2. 输入描述
题目包含多行输入,第一行输入一个数字 N (1 < N <= 20),表示后面有N组测试数据。之后N行都是一个整数,1表示使用电脑本身的TypeC接口,2表示使用扩展坞的USB接口充电。
3. 输出描述
根据每行输入,输出相应的充电信息。
4. C++编码实例
方法一为普通的直接调用;方法二为通过适配器类(TypeCAdapter)去调用被适配(TypeC)来转换为原有的目标对象(Usb),这样就完成了适配器模式的核心思想:搭建桥梁。
/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file AdapterMode.hpp
* @brief 适配器模式
* @autor 写代码的小恐龙er
* @date 2024/01/10
*/
#include<iostream>
#include<string>
using namespace std;
// 原有的USB类 -- 目标接口
class Usb
{
public:
virtual void ChargeWithUsb() = 0;
};
// Typec类 -- 被适配者类
class TypeC{
public:
virtual void ChargeWithTypeC() = 0;
};
// 适配器类 通过持有 被适配者类的实例及方法 来完成桥梁搭建
class TypeCAdapter : public Usb
{
// 持有一个 (被适配者)TypeC的类的实例
private:
TypeC * _typeC;
// 构造函数
public:
TypeCAdapter(TypeC * typeC){
this->_typeC = typeC;
}
//重载接口函数 -- 利用USB充电
void ChargeWithUsb() override{
// 调用被适配者类的方法 -- 利用TypeC充电
_typeC->ChargeWithTypeC();
}
};
// 新电脑 -- 使用 TypeC 接口
class NewComputer : public TypeC
{
public:
// 重载TypeC的充电函数
void ChargeWithTypeC() override {
std::cout << "TypeC" << endl;
}
};
// USB适配器的充电器
class UsbAdapterCharge : public Usb
{
public:
void ChargeWithUsb() override{
std::cout << "USB Adapter" << endl;
}
};
// 【方法一】:这种方法没用到适配器类的桥梁作用
// int main()
// {
// // 测试组数
// int testNum = 0;
// std::cin >> testNum;
// for(int i = 0; i < testNum; i++)
// {
// int choice = 0;
// std::cin >> choice;
// if(choice == 1)
// {
// NewComputer *newComputer = new NewComputer();
// newComputer->ChargeWithTypeC();
// delete newComputer;
// newComputer = nullptr;
// }
// else if(choice == 2)
// {
// UsbAdapterCharge *usbAdapter = new UsbAdapterCharge();
// usbAdapter->ChargeWithUsb();
// delete usbAdapter;
// usbAdapter = nullptr;
// }
// else continue;
// }
// return 0;
// }
// 【方法二】: 利用适配器来进行被适配者类的调用
int main()
{
// 测试组数
int testNum = 0;
std::cin >> testNum;
for(int i = 0; i < testNum; i++)
{
int choice = 0;
std::cin >> choice;
if(choice == 1)
{
// 均为 统一的原有接口 USB
Usb *usb = new TypeCAdapter(new NewComputer());
usb->ChargeWithUsb();
delete usb;
usb = nullptr;
}
else if(choice == 2)
{
// 均为 统一的原有接口 USB
Usb *usbAdapter = new UsbAdapterCharge();
usbAdapter->ChargeWithUsb();
delete usbAdapter;
usbAdapter = nullptr;
}
else continue;
}
return 0;
}
......
To be continued.