用C语言实现外观模式
外观模式(Facade Pattern)的核心是为复杂系统提供一个简化的统一接口,隐藏系统内部的复杂性,使客户端能更轻松地使用系统。在C语言中,可以通过封装多个子模块的接口,提供一个高层接口函数实现:客户端只需调用外观接口,无需直接操作底层子模块。
C语言实现外观模式的思路
- 子系统(Subsystem):由多个相互关联的模块组成,每个模块有自己的接口(如函数)。
- 外观(Facade):封装子系统的接口,提供一个简化的高层接口,协调子系统的调用流程。
- 客户端(Client):仅与外观交互,无需了解子系统的内部细节。
示例:智能家居控制系统(简化多个设备的操作)
假设一个智能家居系统包含灯光、空调、窗帘等子系统,每个子系统有复杂的控制逻辑(如开灯、调温、关窗帘)。外观模式可提供一个“一键离家”接口,自动关闭所有设备,简化操作。
步骤1:定义子系统(各设备模块)
子系统包含多个独立的设备控制逻辑,各自有不同的接口。
#include <stdio.h>// 子系统1:灯光控制
typedef struct {int is_on; // 灯光状态:0-关,1-开
} Light;// 初始化灯光
void light_init(Light* light) {light->is_on = 0;printf("灯光初始化完成(关闭状态)\n");
}// 打开灯光
void light_turn_on(Light* light) {light->is_on = 1;printf("灯光已打开\n");
}// 关闭灯光
void light_turn_off(Light* light) {light->is_on = 0;printf("灯光已关闭\n");
}// 子系统2:空调控制
typedef struct {int is_on; // 空调状态:0-关,1-开int temp; // 温度(℃)
} AirConditioner;// 初始化空调
void ac_init(AirConditioner* ac) {ac->is_on = 0;ac->temp = 26; // 默认温度printf("空调初始化完成(关闭状态,默认26℃)\n");
}// 打开空调并设置温度
void ac_turn_on(AirConditioner* ac, int temp) {ac->is_on = 1;ac->temp = temp;printf("空调已打开,温度设置为%d℃\n", temp);
}// 关闭空调
void ac_turn_off(AirConditioner* ac) {ac->is_on = 0;printf("空调已关闭\n");
}// 子系统3:窗帘控制
typedef struct {int is_closed; // 窗帘状态:0-开,1-关
} Curtain;// 初始化窗帘
void curtain_init(Curtain* curtain) {curtain->is_closed = 0;printf("窗帘初始化完成(打开状态)\n");
}// 关闭窗帘
void curtain_close(Curtain* curtain) {curtain->is_closed = 1;printf("窗帘已关闭\n");
}// 打开窗帘
void curtain_open(Curtain* curtain) {curtain->is_closed = 0;printf("窗帘已打开\n");
}
步骤2:实现外观(统一控制接口)
外观封装所有子系统,提供简化的接口(如“离家模式”“回家模式”),内部协调子系统的调用顺序。
// 外观:智能家居控制器
typedef struct {Light light; // 包含灯光子系统AirConditioner ac; // 包含空调子系统Curtain curtain; // 包含窗帘子系统
} SmartHomeFacade;// 初始化外观(内部初始化所有子系统)
void smart_home_init(SmartHomeFacade* facade) {printf("\n=== 初始化智能家居系统 ===\n");light_init(&facade->light);ac_init(&facade->ac);curtain_init(&facade->curtain);
}// 外观接口1:离家模式(关闭所有设备)
void smart_home_leave_mode(SmartHomeFacade* facade) {printf("\n=== 执行离家模式 ===\n");light_turn_off(&facade->light); // 关闭灯光ac_turn_off(&facade->ac); // 关闭空调curtain_close(&facade->curtain); // 关闭窗帘
}// 外观接口2:回家模式(打开常用设备)
void smart_home_arrive_mode(SmartHomeFacade* facade) {printf("\n=== 执行回家模式 ===\n");light_turn_on(&facade->light); // 打开灯光ac_turn_on(&facade->ac, 24); // 打开空调(24℃)curtain_open(&facade->curtain); // 打开窗帘
}
步骤3:使用外观模式
客户端只需调用外观提供的简化接口,无需直接操作子系统。
int main() {// 创建外观对象SmartHomeFacade home;// 初始化系统(通过外观)smart_home_init(&home);// 回家:调用外观的回家模式smart_home_arrive_mode(&home);// 离家:调用外观的离家模式smart_home_leave_mode(&home);return 0;
}
输出结果
=== 初始化智能家居系统 ===
灯光初始化完成(关闭状态)
空调初始化完成(关闭状态,默认26℃)
窗帘初始化完成(打开状态)=== 执行回家模式 ===
灯光已打开
空调已打开,温度设置为24℃
窗帘已打开=== 执行离家模式 ===
灯光已关闭
空调已关闭
窗帘已关闭
核心思想总结
- 简化接口:外观将多个子系统的复杂接口(如
light_turn_on
、ac_turn_on
)封装为少数几个高层接口(如smart_home_arrive_mode
),降低客户端使用难度。 - 隐藏细节:客户端无需了解子系统的内部实现(如灯光的
is_on
状态、空调的温度控制逻辑),只需通过外观交互。 - 解耦客户端与子系统:子系统的修改(如新增设备、修改控制逻辑)只需调整外观,无需修改客户端代码,符合迪米特法则(最少知识原则)。
C语言通过结构体包含子系统对象,结合函数封装子系统调用流程,实现了外观模式的核心。这种模式适合整合多个复杂模块(如硬件驱动、第三方库、子系统),为上层提供简洁接口。