提示:用C语言实现适配器模式
文章目录
前言
提示:用C语言实现适配器模式:
适配器模式(Adapter Pattern) 是作为两个不兼容接口之间的桥梁, 这种类型的设计模式属于结构型模式。 适配器模式主要分为三类: 类适配器模式、 对象适配器模式、 接口适配器模式。 以生活中手机充电为例来讲解适配器模式, 手机本身并不能直接用220V交流电, 需要将220V的交流电转换为5V的直流电, 在这个过程中, 充电器本身相当于Adapter(适配器) , 220V交流电相当于Adaptee (适配者), 5V直流电则是我们的Target(目标) 。
以手机充电器为例:220V作为源,5V作为目标,充电器就是适配器
一、源
1.源接口:定义220V电压类
struct source
{
int (*output220V)(void);
};
2.源方法:实现220V电压输出方法
int source_output220V(void)
{
printf("源电压是 220V ...\n");
return 220;
}
3.创建源:相当于构造函数
struct source* source_create(void)
{
struct source* src = (struct source*)malloc(sizeof(struct source));
src->output220V = source_output220V;
return src;
}
二、目标
struct adapter; //先声明下适配器的结构体
// 目标接口:定义5V电压类
struct target
{
int (*output5V)(struct adapter* this);
};
三、适配器
1.适配器接口:定义适配器类,继承于220V电压类,并实现5V电压接口
struct adapter
{
struct source* src;
struct target tag;
};
2.适配器方法:实现5V电压输出方法(适配器的目标成员里面的方法指向调用此函数实现输出目标电压)
int VoltageAdapter_output5V(struct adapter* this)
{
int output220V = this->src->output220V(); // 获取220V交流电
int output5V = output220V / 44; // 转换为5V直流电
printf("源电压通过适配器转换后输出目标电压 5V ...\n");
return output5V;
}
3.创建适配器:相当于构造函数
struct adapter* adapter_create(struct source* source)
{
struct adapter* adapter = (struct adapter *)malloc(sizeof(struct adapter *));
adapter->src = source;
adapter->tag.output5V = (int (*)())VoltageAdapter_output5V;
return adapter;
}
四、测试
int main(void)
{
bsp_Init();
int volt;
// 创建源,并初始化
struct source* source = source_create();
// 创建适配器,并初始化
struct adapter* adapter = adapter_create(source);
// 调用适配器adapter的方法得到目标电压
volt = adapter->tag.output5V(adapter);
if(volt == 5)
{
printf("电压刚好5V, 可以充电\n");
}
else if(volt > 5)
{
printf("电压大于5V, 不能充电\n");
}
// 释放内存
free(adapter);
free(source);
}
结果:
代码汇总
/***********************************************************************
源
***********************************************************************/
// 源接口:定义220V电压类
struct source
{
int (*output220V)(void);
};
// 源方法:实现220V电压输出方法
int source_output220V(void)
{
printf("源电压是 220V ...\n");
return 220;
}
// 创建源:相当于构造函数
struct source* source_create(void)
{
struct source* src = (struct source*)malloc(sizeof(struct source));
src->output220V = source_output220V;
return src;
}
/***********************************************************************
目标
***********************************************************************/
struct adapter; //先声明下适配器的结构体
// 目标接口:定义5V电压类
struct target
{
int (*output5V)(struct adapter* this);
};
/***********************************************************************
适配器
***********************************************************************/
// 适配器接口:定义适配器类,继承于220V电压类,并实现5V电压接口
struct adapter
{
struct source* src;
struct target tag;
};
// 适配器方法:实现5V电压输出方法(适配器的目标成员里面的方法指向调用此函数实现输出目标电压)
int VoltageAdapter_output5V(struct adapter* this)
{
int output220V = this->src->output220V(); // 获取220V交流电
int output5V = output220V / 44; // 转换为5V直流电
printf("源电压通过适配器转换后输出目标电压 5V ...\n");
return output5V;
}
// 创建适配器:相当于构造函数
struct adapter* adapter_create(struct source* adaptee)
{
struct adapter* adapter = (struct adapter *)malloc(sizeof(struct adapter *));
adapter->src = adaptee;
adapter->tag.output5V = (int (*)())VoltageAdapter_output5V;
return adapter;
}
int main(void)
{
bsp_Init();
int volt;
// 创建源,并初始化
struct source* source = source_create();
// 创建适配器,并初始化
struct adapter* adapter = adapter_create(source);
// 调用适配器adapter的方法得到目标电压
volt = adapter->tag.output5V(adapter);
if(volt == 5)
{
printf("电压刚好5V, 可以充电\n");
}
else if(volt > 5)
{
printf("电压大于5V, 不能充电\n");
}
// 释放内存
free(adapter);
free(source);
}
五、变更一下
/***********************************************************************
源
***********************************************************************/
// 源接口:定义220V电压类
struct source
{
int (*output220V)(void);
};
// 源方法:实现220V电压输出方法
int source_output220V(void)
{
printf("源电压是 220V ...\n");
return 220;
}
// 创建源:相当于构造函数
struct source* source_create(void)
{
struct source* src = (struct source*)malloc(sizeof(struct source));
src->output220V = source_output220V;
return src;
}
/***********************************************************************
目标
***********************************************************************/
struct adapter; //先声明下适配器的结构体
// 目标接口:定义5V电压类
struct target
{
int (*output5V)(struct adapter* this);
};
/***********************************************************************
适配器
***********************************************************************/
// 适配器接口:定义适配器类,继承于220V电压类,并实现5V电压接口
struct adapter
{
struct source* src;
struct target* tag;
};
// 适配器方法:实现5V电压输出方法(适配器的目标成员里面的方法指向调用此函数实现输出目标电压)
int VoltageAdapter_output5V(struct adapter* this)
{
int output220V = this->src->output220V(); // 获取220V交流电
int output5V = output220V / 44; // 转换为5V直流电
printf("源电压通过适配器转换后输出目标电压 5V ...\n");
return output5V;
}
// 创建适配器:相当于构造函数
struct adapter* adapter_create(struct source* source,struct target* target)
{
struct adapter* adapter = (struct adapter *)malloc(sizeof(struct adapter *));
adapter->src = source;
adapter->tag = target;
target->output5V = VoltageAdapter_output5V;
return adapter;
}
int main(void)
{
bsp_Init();
int volt;
// 创建源,并初始化
struct source* source = source_create();
// 创建目标
struct target* target = (struct target *)malloc(sizeof(struct target *));
// 创建适配器,并初始化
struct adapter* adapter = adapter_create(source,target);
// 调用适配器adapter的方法得到目标电压
volt = adapter->tag->output5V(adapter);
if(volt == 5)
{
printf("电压刚好5V, 可以充电\n");
}
else if(volt > 5)
{
printf("电压大于5V, 不能充电\n");
}
// 释放内存
free(adapter);
free(target);
free(source);
}
六、最终优化
/***********************************************************************
源
***********************************************************************/
// 源接口:定义220V电压类
struct source
{
int volt;
void (*output220V)(int);
};
// 源方法:实现220V电压输出方法
void source_output220V(int volt)
{
printf("源电压是 %dV ...\n",volt);
}
// 创建源:相当于构造函数
struct source* source_create(void)
{
struct source* src = (struct source*)malloc(sizeof(struct source));
src->volt = 220;
src->output220V = source_output220V;
return src;
}
/***********************************************************************
目标
***********************************************************************/
struct adapter; //先声明下适配器的结构体
// 目标接口:定义5V电压类
struct target
{
int volt;
void (*output5V)(struct adapter* adapter);
};
// 创建目标:相当于构造函数
struct target* target_create(void)
{
struct target* target = (struct target*)malloc(sizeof(struct target));
return target;
}
/***********************************************************************
适配器
***********************************************************************/
// 适配器接口:定义适配器类,继承于220V电压类,并实现5V电压接口
struct adapter
{
struct source* src;
struct target* tag;
};
// 适配器方法:实现5V电压输出方法(适配器的目标成员里面的方法指向调用此函数实现输出目标电压)
void VoltageAdapter_output5V(struct adapter* adapter)
{
int output220V = adapter->src->volt; // 获取220V交流电
int output5V = output220V / 44; // 转换为5V直流电
adapter->tag->volt = output5V; // 通过适配器把5V电压赋值给了 目标的volt属性
printf("目标通过适配器从源电压得到了 %dV ...\n",adapter->tag->volt);
}
// 创建适配器:相当于构造函数
struct adapter* adapter_create(struct source* source,struct target* target)
{
struct adapter* adapter = (struct adapter *)malloc(sizeof(struct adapter *));
adapter->src = source;
adapter->tag = target;
target->output5V = VoltageAdapter_output5V;
return adapter;
}
int main(void)
{
bsp_Init();
/* 创建源,并初始化 */
struct source* source = source_create();
source->output220V(source->volt); // 源电压是 220V ...
/* 创建目标 */
struct target* target = target_create();
/* 创建适配器,并初始化 */
struct adapter* adapter = adapter_create(source,target);
/* 调用适配器adapter的方法得到目标电压 */
adapter->tag->output5V(adapter); // 目标通过适配器从源电压得到了 5V ...
/* 判断目标电压是否正确 */
if(target->volt == 5)
{
printf("电压刚好5V, 可以充电\n");
}
else if(target->volt > 5)
{
printf("电压大于5V, 不能充电\n");
}
// 释放内存
free(adapter);
free(target);
free(source);
}
适配器模式通常在以下情况下使用:
当系统中存在现有接口和需要使用的接口不兼容时,可以引入适配器模式来使两者能够协同工作。
当需要复用已有的类,但其接口与系统要求不匹配时,可以使用适配器模式进行接口转换。
当需要通过适配器添加额外的功能或进行数据格式的转换时,可以使用适配器模式来实现。
在嵌入式软件开发中,适配器模式的应用相对较多。这是因为在嵌入式系统中,可能会使用各种不同的硬件模块、驱动程序和通信协议等。这些组件往往具有不同的接口和数据格式,需要通过适配器来协调它们的工作。
例如,在一个嵌入式系统开发中,你可能需要使用一个特定的传感器模块,但它的接口与你的系统框架不匹配。这时,你可以编写一个适配器,将传感器模块的接口转换为系统期望的接口,使其能够与系统其它组件进行协调工作。
适配器模式的使用可以帮助解决接口不兼容的问题,增加代码的可复用性,并降低系统的耦合度。
总之,在嵌入式软件开发中,适配器模式是一种常用的设计模式,用于处理不同组件间接口不兼容的情况,提高系统的灵活性和可扩展性。
七、以下是一个简单的使用适配器模式的嵌入式系统示例(使用C语言):
// 现有传感器模块的接口
typedef struct {
int id;
int value;
// 其他属性和方法
} SensorModule;
// 期望的系统接口
typedef struct {
int id;
int data;
// 其他属性和方法
} SystemInterface;
// 适配器对象
typedef struct {
SensorModule* sensor;
SystemInterface* system;
} Adapter;
// 适配器的转换方法
void convertData(Adapter* adapter) {
adapter->system->id = adapter->sensor->id;
adapter->system->data = adapter->sensor->value * 2;
// 其他数据转换逻辑
}
int main(void)
{
bsp_Init();
SensorModule sensor;
sensor.id = 1;
sensor.value = 10;
SystemInterface system;
Adapter adapter;
adapter.sensor = &sensor;
adapter.system = &system;
convertData(&adapter);
printf("转换后的数据:ID: %d, Data: %d\n", system.id, system.data);
}
在以上示例中,我们有一个现有的传感器模块(SensorModule),它的接口与我们的系统期望的接口(SystemInterface)不匹配。我们通过创建一个适配器对象(Adapter),将传感器模块的接口适配为系统期望的接口。
通过适配器的转换方法(convertData),我们将传感器模块的数据转换为系统期望的格式,并将其赋值给系统接口对象。
在主函数中,我们创建了一个传感器模块对象、一个系统接口对象和一个适配器对象,并通过适配器将传感器模块的数据转换为系统接口期望的格式。最后,我们可以打印出转换后的数据。
请注意,这只是一个简化的示例,实际系统中可能会涉及更复杂的数据转换和逻辑。然而,这个示例演示了如何使用适配器模式来处理不同接口之间的兼容性问题,并实现数据的转换。