前言
软软件设计模式(Design pattern),简称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。--来自百度百科。既然设计模式有那么多好处,我们在做程序设计的时候,就应该充分考虑自己需要解决的问题是否有一个设计模式与之相似,尽量使用现有的解决方案来设计程序,避免代码重复或自己考虑不足导致设计缺陷。
本周五参加了设计模式研讨会,讨论的主题就是桥接模式(bridge),这篇博文的目的是对桥接模式的总结,以及分享一个桥接模式的C语言应用例子,希望对想学习这个模式的同学有所帮助。
一、桥接模式总结
1、模式意图
将抽象部分和实现部分分离,使他们可以独立地变化。2、参与者
Abstraction--定义抽象类的接口,维护一个指向Implementor类型对象的指针。
RefinedAbstraction
-- 扩充Abstraction定义的接口。
Implementor
-- 定义实现类的接口,该接口不一定要和Abstraction的接口完全一致,Implementor接口仅提供基本操作,Abstraction则定义了基于这些操作的比较高层次的操作。
ConcreteImplementor
-- 实现Implementor接口。
3、结构及效果
结构图:1、分离接口及其实现部分。
2、提高可扩展性。
3、实现细节对客户透明。
4、适用性
1、你不希望在抽象和它的实现之间有一个固定的绑定关系。2、类的抽象及实现都应该可以通过生成子类来扩展功能。
3、对一个抽象的实现部分的修改不应该影响客户。
4、对客户隐藏实现细节。
5、多个对象共享实现,但客户并不知道这一点。
二、桥接模式C语言用例
1、用例背景描述
在跨平台应用程序,代码一般是通过宏定义来条件编译,区分不同平台的代码。但是,使用宏定义的方式,只能用于代码量较小的程序,如果程序代码量特别大, 或者系统平台比较多,使用宏定义的方式来区分不同平台的代码,将会使代码的可读性变得非常差,也不利于代码维护。而使用桥接模式,定义的接口可以在不同平台上共享而无需修改,每个平台只需提供一个本平台的一个具体实现即可。这样的方式,接口和实现分离,接口和实现两个部分可以独立变化,互不干扰。下边举的一个例子是桥接模式在网络接口设计中的应用,接口定义各平台统一的接口if_info_t,具体平台实现if_info_impl_t实现接口。这样if_info_t在客户代码中应用,移植不同平台时,不需要修改代码。而每个具体平台实现if_info_impl_t,实现网络接口功能,同时也可以扩展本平台其他的功能,可以独立变化而不影响接口。
2、用例结构图
if_info_impl_t:具体平台的接口,桥接模式中的Implementor;
if_info_linux_impl_t:Linux平台网络接口实现类,桥接模式中的ConcreteImplementor;
if_info_linux_impl_t:Windows平台网络接口实现类,桥接模式中的ConcreteImplementor;
3、C语言代码实现
为了代码使代码简洁,这里成员函数只贴一个get_ip即可,只要整体代码结构体现出桥接模式的即可。1、if_info_t 定义及实现:
该类定义统一的网络接口,必须获取网络设备的IP地址:get_ip。在对象创建函数if_info_create内部,通过创建一个抽象工厂对象,由工厂负责获取具体平台的if_info_impl_t对象。一般工厂只有一个,if_info_factory_create内部实现应该是单例。客户使用这个类,并不会涉及具体的实现类的任何细节,移植到不同平台,客户代码是不需要改变的。在工厂当中,根据特定的平台,产生该平台的实现类对象即可。
//.h
typedef struct _if_info_t if_info_t;
typedef char* (*get_ip_t)(const char* interface_name);
/**
* @class if_info_t
* 网卡接口。
*/
struct _if_info_t {
if_info_impl_t* impl;
char* interface_name;
int8_t type;
};
if_info_t* if_info_create(const char* interface_name, int8_t type);
char* get_ip(if_info_t* interface);
//.c
char* get_ip(if_info_t* interface) {
return interface->impl->get_ip(interface->interface_name);
}
if_info_t* if_info_create(const char* interface_name, int8_t type) {
if_info_t* if_info = TKMEM_ZALLOC(if_info_t);
if_info_impl_t* impl = if_info_factory_create()->get_if_info();
if_info->impl = impl;
if_info->interface_name = tk_strdup(interface_name);;
if_info->type = type;
return if_info ;
}
2、if_info_impl_t 定义:
定义实现类的统一接口。
//.h
/**
* @class if_info_impl_t
* 网卡实现接口。
*/
struct if_info_impl_t {
get_ip_t get_ip;
};
}
3、if_info_linux_impl_t 定义及实现:
定义Linux平台的实现类。get_ip获取该平台的IP地址。if_info_linux_impl_create创建Linux平台实现类对象,这个函数可以供工厂使用。
//.h
/**
* @class if_info_linux_impl_t
* 网卡接口--linux。
*/
struct if_info_linux_impl_t {
if_info_impl_t parent;
};
//.c
char* get_ip(const char* interface_name) {
return get_ip_by_interface_name(interface_name);
}
if_info_impl_t* if_info_linux_impl_create(const char* interface_name, int8_t type) {
if_info_linux_impl_t* linux_network_interface = TKMEM_ZALLOC(if_info_linux_impl_t);
return_value_if_fail(linux_network_interface != NULL, NULL);
if_info_impl_t* parent = (if_info_impl_t*)linux_network_interface;
parent->get_ip = get_ip;
return parent;
}
4、if_info_windows_impl_t 定义及实现:
定义Windows平台的实现类。get_ip获取该平台的IP地址。if_info_windows_impl_create创建Windows平台实现类对象,这个函数可以供工厂使用。
//.h
/**
* @class if_info_windows_impl_t
* 网卡接口--linux。
*/
struct if_info_windows_impl_t {
if_info_impl_t parent;
};
//.c
char* get_ip(const char* interface_name) {
return get_ip_by_interface_name(interface_name);
}
if_info_impl_t* if_info_windows_impl_create(const char* interface_name, int8_t type) {
if_info_windows_impl_t* windows_network_interface = TKMEM_ZALLOC(if_info_windows_impl_t);
return_value_if_fail(windows_network_interface != NULL, NULL);
if_info_impl_t* parent = (if_info_impl_t*)windows_network_interface;
parent->get_ip = get_ip;
return parent;
}