文章目录
-
-
- [模板方法模式在 C 语言中的应用(含 Linux 内核实例)](#模板方法模式在 C 语言中的应用(含 Linux 内核实例))
-
- 一、模板方法模式的定义与核心价值
- [二、C 语言实现模板方法模式的核心思路](#二、C 语言实现模板方法模式的核心思路)
- [三、 5 个实例](#三、 5 个实例)
-
- [实例 1:基础模板方法(数据处理流程)](#实例 1:基础模板方法(数据处理流程))
- [实例 2:设备初始化模板(硬件启动流程)](#实例 2:设备初始化模板(硬件启动流程))
- [实例 3:网络请求模板(HTTP/HTTPS 请求流程)](#实例 3:网络请求模板(HTTP/HTTPS 请求流程))
- [实例 4:测试用例模板(单元测试流程)](#实例 4:测试用例模板(单元测试流程))
- [实例 5:内核风格模板(模块加载流程)](#实例 5:内核风格模板(模块加载流程))
- [四、Linux 内核中的模板方法模式应用](#四、Linux 内核中的模板方法模式应用)
- 五、实现注意事项
- 六、补充说明
-
模板方法模式在 C 语言中的应用(含 Linux 内核实例)
一、模板方法模式的定义与核心价值
模板方法模式(Template Method Pattern)是一种行为型设计模式,其核心是定义一个操作的算法骨架(模板方法),将算法中的某些步骤延迟到子类(或具体实现)中实现。模板方法固定了算法的整体流程,而允许具体步骤的实现灵活变化,从而在保证流程一致性的同时,支持步骤实现的多样性。
存在的意义:当多个算法或流程具有相同的整体框架,但部分步骤的实现细节不同时(如 "初始化→处理→清理" 的流程),直接重复实现框架会导致代码冗余,且难以修改框架需同步修改所有实现。模板方法模式通过提取公共框架作为模板,将可变步骤步骤抽象为可重写的接口,实现 "框架复用、细节定制"。
解决的问题:
- 多个相似流程重复实现公共框架,代码冗余且维护成本高;
- 公共框架修改需同步调整所有相关实现,易引入错误;
- 流程步骤的调用顺序分散在各个实现中,难以保证一致性。
二、C 语言实现模板方法模式的核心思路
C 语言通过 ** 函数指针 + 结构体组合实现模板方法模式:
- 定义模板框架(Template):结构体包含模板方法(固定流程的函数),以及指向抽象步骤的函数指针(需具体实现的步骤);
- 实现模板方法:在模板方法中按固定顺序调用抽象步骤的函数指针,构成完整算法流程;
- 派生具体实现:通过初始化结构体的函数指针,为抽象步骤提供具体实现,复用模板方法的流程框架。

三、 5 个实例
实例 1:基础模板方法(数据处理流程)
模拟 "读取数据→处理数据→保存结果" 的固定流程,其中 "处理数据" 步骤可定制。
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 1. 模板框架:数据处理器
typedef struct {
// 抽象步骤(需具体实现)
void (*read_data)(struct DataProcessor* self, const char* filename);
void (*process_data)(struct DataProcessor* self);
void (*save_result)(struct DataProcessor* self, const char* filename);
// 模板方法(固定流程)
void (*execute)(struct DataProcessor* self, const char* infile, const char* outfile);
// 数据缓冲区
char data[1024];
} DataProcessor;
// 模板方法:固定流程
static void data_processor_execute(DataProcessor* self, const char* infile, const char* outfile) {
printf("=== Starting data processing ===\n");
self->read_data(self, infile); // 步骤1:读取数据
self->process_data(self); // 步骤2:处理数据(可变)
self->save_result(self, outfile); // 步骤3:保存结果
printf("=== Processing completed ===\n");
}
// 初始化模板框架(绑定模板方法)
void init_data_processor(DataProcessor* self) {
self->execute = data_processor_execute;
// 抽象步骤初始化为NULL(需具体实现填充)
self->read_data = NULL;
self->process_data = NULL;
self->save_result = NULL;
}
// 2. 具体实现1:大写转换处理器(处理步骤为字符串大写)
static void upper_read(DataProcessor* self, const char* filename) {
// 模拟读取文件
snprintf(self->data, sizeof(self->data), "hello from %s", filename);
printf("Read data: %s\n", self->data);
}
static void upper_process(DataProcessor* self) {
// 处理步骤:转为大写
for (int i = 0; self->data[i]; i++) {
if (self->data[i] >= 'a' && self->data[i] <= 'z') {
self->data[i] -= 32;
}
}
printf("Processed data (upper): %s\n", self->data);
}
static void upper_save(DataProcessor* self, const char* filename) {
// 模拟保存文件
printf("Saved result to %s: %s\n", filename, self->data);
}
// 创建大写转换处理器
DataProcessor* create_upper_processor() {
DataProcessor* proc = malloc(sizeof(DataProcessor));
init_data_processor(proc);
// 绑定具体步骤
proc->read_data = upper_read;
proc->process_data = upper_process;
proc->save_result = upper_save;
return proc;
}
// 具体实现2:反转字符串处理器(处理步骤为字符串反转)
static void reverse_read(DataProcessor* self, const char* filename) {
// 复用类似的读取逻辑
snprintf(self->data, sizeof(self->data), "hello from %s", filename);
printf("Read data: %s\n", self->data);
}
static void reverse_process(DataProcessor* self) {
// 处理步骤:反转字符串
int len = strlen(self->data);
for (int i = 0; i < len/2; i++) {
char temp = self->data[i];
self->data[i] = self->data[len - i - 1];
self->data[len - i - 1] = temp;
}
printf("Processed data (reverse): %s\n", self->data);
}
static void reverse_save(DataProcessor* self, const char* filename) {
// 复用类似的保存逻辑
printf("Saved result to %s: %s\n", filename, self->data);
}
// 创建反转处理器
DataProcessor* create_reverse_processor() {
DataProcessor* proc = malloc(sizeof(DataProcessor));
init_data_processor(proc);
proc->read_data = reverse_read;
proc->process_data = reverse_process;
proc->save_result = reverse_save;
return proc;
}
// 客户端使用
int main() {
// 使用大写转换处理器
printf("--- Upper Processor ---\n");
DataProcessor* upper = create_upper_processor();
upper->execute(upper, "input.txt", "upper_out.txt");
// 使用反转处理器
printf("\n--- Reverse Processor ---\n");
DataProcessor* reverse = create_reverse_processor();
reverse->execute(reverse, "input.txt", "reverse_out.txt");
free(upper);
free(reverse);
return 0;
}
以上代码执行结果如下
--- Upper Processor ---
=== Starting data processing ===
Read data: hello from input.txt
Processed data (upper): HELLO FROM INPUT.TXT
Saved result to upper_out.txt: HELLO FROM INPUT.TXT
=== Processing completed ===
--- Reverse Processor ---
=== Starting data processing ===
Read data: hello from input.txt
Processed data (reverse): txt.tupni morf olleh
Saved result to reverse_out.txt: txt.tupni morf olleh
=== Processing completed ===
其UML图例如下所示

即::DataProcessor定义了 "读取→处理→保存" 的固定流程(模板方法execute),upper_process和reverse_process分别实现了不同的 "处理" 逻辑,复用了相同的流程框架,符合模板方法 "固定骨架、定制细节" 的核心思想。
实例 2:设备初始化模板(硬件启动流程)
模拟硬件设备 "上电→初始化寄存器→自检→使能" 的固定启动流程,其中 "初始化寄存器" 步骤因设备而异。
c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
// 1. 模板框架:设备启动器
typedef struct {
// 抽象步骤
void (*power_on)(struct DeviceBootstrapper* self);
void (*init_registers)(struct DeviceBootstrapper* self); // 设备相关步骤
bool (*self_test)(struct DeviceBootstrapper* self);
void (*enable)(struct DeviceBootstrapper* self);
// 模板方法:固定启动流程
bool (*boot)(struct DeviceBootstrapper* self);
// 设备信息
const char* name;
uint32_t reg_base; // 寄存器基地址
} DeviceBootstrapper;
// 模板方法:固定启动流程
static bool device_boot(DeviceBootstrapper* self) {
printf("=== Booting %s ===\n", self->name);
self->power_on(self);
self->init_registers(self);
if (!self->self_test(self)) {
printf("Boot failed: self-test failed\n");
return false;
}
self->enable(self);
printf("=== %s booted successfully ===\n", self->name);
return true;
}
// 初始化模板框架
void init_device_bootstrapper(DeviceBootstrapper* self, const char* name, uint32_t reg_base) {
self->name = name;
self->reg_base = reg_base;
self->boot = device_boot;
// 抽象步骤初始化为NULL
self->power_on = NULL;
self->init_registers = NULL;
self->self_test = NULL;
self->enable = NULL;
}
// 2. 具体实现1:UART设备启动
static void uart_power_on(DeviceBootstrapper* self) {
printf("[%s] Powering on UART\n", self->name);
}
static void uart_init_registers(DeviceBootstrapper* self) {
// UART特有的寄存器初始化
printf("[%s] Initializing UART registers at 0x%08X\n", self->name, self->reg_base);
printf(" - Setting baud rate to 115200\n");
printf(" - Enabling TX/RX pins\n");
}
static bool uart_self_test(DeviceBootstrapper* self) {
printf("[%s] Performing UART loopback test... OK\n", self->name);
return true;
}
static void uart_enable(DeviceBootstrapper* self) {
printf("[%s] Enabling UART controller\n", self->name);
}
// 创建UART启动器
DeviceBootstrapper* create_uart_bootstrapper() {
DeviceBootstrapper* boot = malloc(sizeof(DeviceBootstrapper));
init_device_bootstrapper(boot, "UART0", 0x10000000);
boot->power_on = uart_power_on;
boot->init_registers = uart_init_registers;
boot->self_test = uart_self_test;
boot->enable = uart_enable;
return boot;
}
// 具体实现2:SPI设备启动
static void spi_power_on(DeviceBootstrapper* self) {
printf("[%s] Powering on SPI\n", self->name);
}
static void spi_init_registers(DeviceBootstrapper* self) {
// SPI特有的寄存器初始化
printf("[%s] Initializing SPI registers at 0x%08X\n", self->name, self->reg_base);
printf(" - Setting clock frequency to 1MHz\n");
printf(" - Configuring as master mode\n");
}
static bool spi_self_test(DeviceBootstrapper* self) {
printf("[%s] Performing SPI chip select test... OK\n", self->name);
return true;
}
static void spi_enable(DeviceBootstrapper* self) {
printf("[%s] Enabling SPI controller\n", self->name);
}
// 创建SPI启动器
DeviceBootstrapper* create_spi_bootstrapper() {
DeviceBootstrapper* boot = malloc(sizeof(DeviceBootstrapper));
init_device_bootstrapper(boot, "SPI0", 0x10001000);
boot->power_on = spi_power_on;
boot->init_registers = spi_init_registers;
boot->self_test = spi_self_test;
boot->enable = spi_enable;
return boot;
}
// 客户端使用
int main() {
// 启动UART设备
printf("--- UART Boot ---\n");
DeviceBootstrapper* uart = create_uart_bootstrapper();
uart->boot(uart);
// 启动SPI设备
printf("\n--- SPI Boot ---\n");
DeviceBootstrapper* spi = create_spi_bootstrapper();
spi->boot(spi);
free(uart);
free(spi);
return 0;
}
以上代码执行结果如下
--- UART Boot ---
=== Booting UART0 ===
[UART0] Powering on UART
[UART0] Initializing UART registers at 0x10000000
- Setting baud rate to 115200
- Enabling TX/RX pins
[UART0] Performing UART loopback test... OK
[UART0] Enabling UART controller
=== UART0 booted successfully ===
--- SPI Boot ---
=== Booting SPI0 ===
[SPI0] Powering on SPI
[SPI0] Initializing SPI registers at 0x10001000
- Setting clock frequency to 1MHz
- Configuring as master mode
[SPI0] Performing SPI chip select test... OK
[SPI0] Enabling SPI controller
=== SPI0 booted successfully ===
其UML图例如下所示

即::所有设备遵循 "上电→初始化寄存器→自检→使能" 的固定启动流程(模板方法boot),但init_registers步骤因设备类型(UART/SPI)而异,体现了模板方法在硬件初始化中的典型应用。
实例 3:网络请求模板(HTTP/HTTPS 请求流程)
模拟网络请求 "建立连接→发送请求→接收响应→关闭连接" 的固定流程,其中 "发送请求" 和 "接收响应" 因协议(HTTP/HTTPS)而异。
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 1. 模板框架:网络请求器
typedef struct {
// 抽象步骤
bool (*connect)(struct NetworkRequester* self, const char* host, int port);
bool (*send_request)(struct NetworkRequester* self, const char* path); // 协议相关
bool (*recv_response)(struct NetworkRequester* self, const char* path,char* buffer, int len); // 协议相关
void (*disconnect)(struct NetworkRequester* self);
// 模板方法:固定请求流程
bool (*request)(struct NetworkRequester* self, const char* host, int port, const char* path, char* resp, int len);
// 连接状态
bool is_connected;
} NetworkRequester;
// 模板方法:固定请求流程
static bool network_request(NetworkRequester* self, const char* host, int port, const char* path, char* resp, int len) {
printf("=== Starting network request ===\n");
if (!self->connect(self, host, port)) {
printf("Request failed: connect failed\n");
return false;
}
if (!self->send_request(self, path)) {
self->disconnect(self);
printf("Request failed: send failed\n");
return false;
}
if (!self->recv_response(self, path,resp, len)) {
self->disconnect(self);
printf("Request failed: recv failed\n");
return false;
}
self->disconnect(self);
printf("=== Request completed ===\n");
return true;
}
// 初始化模板框架
void init_network_requester(NetworkRequester* self) {
self->is_connected = false;
self->request = network_request;
// 抽象步骤初始化为NULL
self->connect = NULL;
self->send_request = NULL;
self->recv_response = NULL;
self->disconnect = NULL;
}
// 2. 具体实现1:HTTP请求
static bool http_connect(NetworkRequester* self, const char* host, int port) {
int used_port = (port == 0) ? 80 : port;
printf("HTTP connecting to %s:%d\n", host, used_port);
self->is_connected = true;
return true;
}
static bool http_send_request(NetworkRequester* self, const char* path) {
if (!self->is_connected) return false;
printf("HTTP sending: GET %s HTTP/1.1\n", path);
return true;
}
static bool http_recv_response(NetworkRequester* self, const char* path,char* buffer, int len) {
if (!self->is_connected) return false;
snprintf(buffer, len, "HTTP/1.1 200 OK\nContent: Hello from %s", path);
printf("HTTP received: %s\n", buffer);
return true;
}
static void http_disconnect(NetworkRequester* self) {
if (self->is_connected) {
printf("HTTP disconnecting\n");
self->is_connected = false;
}
}
// 创建HTTP请求器
NetworkRequester* create_http_requester() {
NetworkRequester* req = malloc(sizeof(NetworkRequester));
init_network_requester(req);
req->connect = http_connect;
req->send_request = http_send_request;
req->recv_response = http_recv_response;
req->disconnect = http_disconnect;
return req;
}
// 具体实现2:HTTPS请求
static bool https_connect(NetworkRequester* self, const char* host, int port) {
int used_port = (port == 0) ? 443 : port;
printf("HTTPS connecting to %s:%d (TLS handshake)\n", host, used_port);
self->is_connected = true;
return true;
}
static bool https_send_request(NetworkRequester* self, const char* path) {
if (!self->is_connected) return false;
printf("HTTPS sending (encrypted): GET %s HTTP/1.1\n", path);
return true;
}
static bool https_recv_response(NetworkRequester* self, const char* path,char* buffer, int len) {
if (!self->is_connected) return false;
snprintf(buffer, len, "HTTPS/1.1 200 OK\nEncrypted Content: Hello from %s", path);
printf("HTTPS received (decrypted): %s\n", buffer);
return true;
}
static void https_disconnect(NetworkRequester* self) {
if (self->is_connected) {
printf("HTTPS disconnecting (TLS close)\n");
self->is_connected = false;
}
}
// 创建HTTPS请求器
NetworkRequester* create_https_requester() {
NetworkRequester* req = malloc(sizeof(NetworkRequester));
init_network_requester(req);
req->connect = https_connect;
req->send_request = https_send_request;
req->recv_response = https_recv_response;
req->disconnect = https_disconnect;
return req;
}
// 客户端使用
int main() {
char resp[512];
// 发送HTTP请求
printf("--- HTTP Request ---\n");
NetworkRequester* http = create_http_requester();
http->request(http, "example.com", 0, "/index.html", resp, sizeof(resp));
// 发送HTTPS请求
printf("\n--- HTTPS Request ---\n");
NetworkRequester* https = create_https_requester();
https->request(https, "example.com", 0, "/secure.html", resp, sizeof(resp));
free(http);
free(https);
return 0;
}
以上代码执行结果如下
--- HTTP Request ---
=== Starting network request ===
HTTP connecting to example.com:80
HTTP sending: GET /index.html HTTP/1.1
HTTP received: HTTP/1.1 200 OK
Content: Hello from /index.html
HTTP disconnecting
=== Request completed ===
--- HTTPS Request ---
=== Starting network request ===
HTTPS connecting to example.com:443 (TLS handshake)
HTTPS sending (encrypted): GET /secure.html HTTP/1.1
HTTPS received (decrypted): HTTPS/1.1 200 OK
Encrypted Content: Hello from /secure.html
HTTPS disconnecting (TLS close)
=== Request completed ===
其UML图例如下所示

即::HTTP 和 HTTPS 请求共享 "连接→发送→接收→断开" 的流程框架(模板方法request),但send_request和recv_response因加密需求不同而实现各异,体现了模板方法对协议细节的封装。
实例 4:测试用例模板(单元测试流程)
模拟单元测试 "初始化→执行测试→清理→验证结果" 的固定流程,其中 "执行测试" 步骤因测试对象而异。
c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 1. 模板框架:测试用例
typedef struct {
// 抽象步骤
void (*setup)(struct TestCase* self); // 初始化
void (*run)(struct TestCase* self); // 执行测试(可变)
void (*teardown)(struct TestCase* self); // 清理
bool (*verify)(struct TestCase* self); // 验证结果
// 模板方法:固定测试流程
bool (*execute)(struct TestCase* self);
// 测试状态
const char* name;
bool passed;
} TestCase;
// 模板方法:固定测试流程
static bool testcase_execute(TestCase* self) {
printf("=== Running test: %s ===\n", self->name);
self->setup(self);
self->run(self);
self->teardown(self);
self->passed = self->verify(self);
printf("Test %s: %s\n", self->name, self->passed ? "PASSED" : "FAILED");
printf("=== Test completed ===\n");
return self->passed;
}
// 初始化模板框架
void init_test_case(TestCase* self, const char* name) {
self->name = name;
self->passed = false;
self->execute = testcase_execute;
// 抽象步骤初始化为NULL
self->setup = NULL;
self->run = NULL;
self->teardown = NULL;
self->verify = NULL;
}
// 2. 具体实现1:加法函数测试
static int add(int a, int b) { return a + b; } // 待测试函数
static void add_setup(TestCase* self) {
(void)self;
printf("Setting up add test\n");
}
static void add_run(TestCase* self) {
(void)self;
printf("Running add test: 2 + 3 = %d\n", add(2, 3));
}
static void add_teardown(TestCase* self) {
(void)self;
printf("Tearing down add test\n");
}
static bool add_verify(TestCase* self) {
(void)self;
return add(2, 3) == 5; // 验证结果
}
// 创建加法测试用例
TestCase* create_add_test() {
TestCase* test = malloc(sizeof(TestCase));
init_test_case(test, "AddTest");
test->setup = add_setup;
test->run = add_run;
test->teardown = add_teardown;
test->verify = add_verify;
return test;
}
// 具体实现2:字符串反转测试
static void reverse_str(char* str) {
int len = 0;
while (str[len]) len++;
for (int i = 0; i < len/2; i++) {
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
} // 待测试函数
static char test_str[32]; // 测试数据
static void reverse_setup(TestCase* self) {
(void)self;
printf("Setting up reverse test\n");
strcpy(test_str, "hello");
}
static void reverse_run(TestCase* self) {
(void)self;
printf("Original string: %s\n", test_str);
reverse_str(test_str);
printf("Reversed string: %s\n", test_str);
}
static void reverse_teardown(TestCase* self) {
(void)self;
printf("Tearing down reverse test\n");
}
static bool reverse_verify(TestCase* self) {
(void)self;
return strcmp(test_str, "olleh") == 0; // 验证结果
}
// 创建反转测试用例
TestCase* create_reverse_test() {
TestCase* test = malloc(sizeof(TestCase));
init_test_case(test, "ReverseTest");
test->setup = reverse_setup;
test->run = reverse_run;
test->teardown = reverse_teardown;
test->verify = reverse_verify;
return test;
}
// 客户端使用
int main() {
// 执行加法测试
printf("--- Add Test ---\n");
TestCase* add_test = create_add_test();
add_test->execute(add_test);
// 执行反转测试
printf("\n--- Reverse Test ---\n");
TestCase* reverse_test = create_reverse_test();
reverse_test->execute(reverse_test);
free(add_test);
free(reverse_test);
return 0;
}
以上代码执行结果如下
--- Add Test ---
=== Running test: AddTest ===
Setting up add test
Running add test: 2 + 3 = 5
Tearing down add test
Test AddTest: PASSED
=== Test completed ===
--- Reverse Test ---
=== Running test: ReverseTest ===
Setting up reverse test
Original string: hello
Reversed string: olleh
Tearing down reverse test
Test ReverseTest: PASSED
=== Test completed ===
其UML图例如下所示

即::所有测试用例遵循 "初始化→执行→清理→验证" 的固定流程(模板方法execute),run步骤因测试对象(加法 / 字符串反转)而异,符合单元测试框架的设计逻辑(如 JUnit 的@Before/@Test/@After)。
实例 5:内核风格模板(模块加载流程)
模拟 Linux 内核模块 "加载→初始化→运行→卸载" 的固定流程,其中 "初始化" 和 "运行" 步骤因模块功能而异。
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 1. 模板框架:内核模块
typedef struct {
// 抽象步骤(内核模块必需接口)
int (*init)(struct KernelModule* self); // 初始化(可变)
void (*run)(struct KernelModule* self); // 运行逻辑(可变)
void (*exit)(struct KernelModule* self); // 清理
// 模板方法:固定模块生命周期
int (*load)(struct KernelModule* self); // 加载流程
int (*unload)(struct KernelModule* self); // 卸载流程
// 模块信息
const char* name;
bool is_loaded;
} KernelModule;
// 模板方法:加载流程
static int module_load(KernelModule* self) {
if (self->is_loaded) {
printf("Module %s is already loaded\n", self->name);
return -1;
}
printf("=== Loading module: %s ===\n", self->name);
int ret = self->init(self); // 初始化(模块特定)
if (ret != 0) {
printf("Module %s init failed (code %d)\n", self->name, ret);
return ret;
}
self->run(self); // 运行(模块特定)
self->is_loaded = true;
printf("Module %s loaded successfully\n", self->name);
return 0;
}
// 模板方法:卸载流程
static int module_unload(KernelModule* self) {
if (!self->is_loaded) {
printf("Module %s is not loaded\n", self->name);
return -1;
}
printf("=== Unloading module: %s ===\n", self->name);
self->exit(self);
self->is_loaded = false;
printf("Module %s unloaded successfully\n", self->name);
return 0;
}
// 初始化模板框架
void init_kernel_module(KernelModule* self, const char* name) {
self->name = name;
self->is_loaded = false;
self->load = module_load;
self->unload = module_unload;
// 抽象步骤初始化为NULL(模块必须实现)
self->init = NULL;
self->run = NULL;
self->exit = NULL;
}
// 2. 具体实现1:网络模块
static int net_init(KernelModule* self) {
printf("[%s] Initializing network module\n", self->name);
printf(" - Registering network interface\n");
return 0; // 初始化成功
}
static void net_run(KernelModule* self) {
printf("[%s] Starting network service (DHCP, DNS)\n", self->name);
}
static void net_exit(KernelModule* self) {
printf("[%s] Cleaning up network module\n", self->name);
printf(" - Unregistering network interface\n");
}
// 创建网络模块
KernelModule* create_net_module() {
KernelModule* mod = malloc(sizeof(KernelModule));
init_kernel_module(mod, "net_module");
mod->init = net_init;
mod->run = net_run;
mod->exit = net_exit;
return mod;
}
// 具体实现2:存储模块
static int storage_init(KernelModule* self) {
printf("[%s] Initializing storage module\n", self->name);
printf(" - Scanning for disks\n");
printf(" - Mounting filesystems\n");
return 0;
}
static void storage_run(KernelModule* self) {
printf("[%s] Starting storage service (I/O scheduling)\n", self->name);
}
static void storage_exit(KernelModule* self) {
printf("[%s] Cleaning up storage module\n", self->name);
printf(" - Unmounting filesystems\n");
}
// 创建存储模块
KernelModule* create_storage_module() {
KernelModule* mod = malloc(sizeof(KernelModule));
init_kernel_module(mod, "storage_module");
mod->init = storage_init;
mod->run = storage_run;
mod->exit = storage_exit;
return mod;
}
// 客户端使用(模拟内核模块管理器)
int main() {
// 加载网络模块
printf("--- Network Module ---\n");
KernelModule* net_mod = create_net_module();
net_mod->load(net_mod);
// 加载存储模块
printf("\n--- Storage Module ---\n");
KernelModule* storage_mod = create_storage_module();
storage_mod->load(storage_mod);
// 卸载模块
printf("\n--- Unloading Modules ---\n");
net_mod->unload(net_mod);
storage_mod->unload(storage_mod);
free(net_mod);
free(storage_mod);
return 0;
}
以上代码执行结果如下
--- Network Module ---
=== Loading module: net_module ===
[net_module] Initializing network module
- Registering network interface
[net_module] Starting network service (DHCP, DNS)
Module net_module loaded successfully
--- Storage Module ---
=== Loading module: storage_module ===
[storage_module] Initializing storage module
- Scanning for disks
- Mounting filesystems
[storage_module] Starting storage service (I/O scheduling)
Module storage_module loaded successfully
--- Unloading Modules ---
=== Unloading module: net_module ===
[net_module] Cleaning up network module
- Unregistering network interface
Module net_module unloaded successfully
=== Unloading module: storage_module ===
[storage_module] Cleaning up storage module
- Unmounting filesystems
Module storage_module unloaded successfully
其UML图例如下所示

即:模拟 Linux 内核模块的生命周期管理,所有模块遵循 "加载→初始化→运行→卸载" 的固定流程(模板方法load/unload),init和run步骤因模块功能(网络 / 存储)而异,与内核中module_init/module_exit的机制一致。
四、Linux 内核中的模板方法模式应用
- 设备驱动模型(
driver与device) :内核设备驱动遵循 "探测(probe)→初始化→运行→移除(remove)" 的固定流程,定义在struct device_driver中。具体驱动只需实现probe和remove等步骤,复用内核的驱动管理框架(模板方法),如driver_register和driver_unregister。 - 文件系统挂载流程 :所有文件系统(如 ext4、btrfs)的挂载流程统一为 "解析超级块→初始化 inode→挂载根目录",定义在 VFS(虚拟文件系统)的模板方法中。具体文件系统通过实现
struct file_system_type中的mount函数(抽象步骤),接入统一的挂载框架。 - 内核模块生命周期 :内核模块必须实现
init_module(初始化)和cleanup_module(清理)接口,模块的加载(sys_init_module)和卸载(sys_delete_module)流程由内核统一管理(模板方法),确保所有模块遵循相同的生命周期规范。 - 网络协议栈初始化 :网络协议(如 TCP、UDP)的初始化流程统一为 "注册协议→初始化套接字→注册钩子函数",定义在
proto_register等模板方法中。具体协议通过实现struct proto中的init等函数(抽象步骤),复用内核的协议注册框架。 - 工作队列处理流程 :工作队列的任务处理遵循 "入队→调度→执行→清理" 的固定流程,定义在
queue_work等模板方法中。用户只需实现work_struct中的func函数(抽象步骤),即可将任务接入工作队列框架,无需关心调度细节。
五、实现注意事项
- 模板方法的不可变性:模板方法(固定流程)应设计为不可修改的核心逻辑,避免具体实现破坏流程一致性。C 语言中可通过将模板方法实现为静态函数(不允许被覆盖),仅暴露抽象步骤的函数指针。
- 抽象步骤的完整性 :确保所有抽象步骤在具体实现中被正确初始化(避免空指针),可在模板方法中添加检查逻辑,对未实现的步骤报错(如
if (!self->step) { fprintf(stderr, "Step not implemented"); })。 - 流程的扩展性 :模板方法应预留扩展点(如在固定步骤之间插入可选的钩子函数),例如在 "初始化→处理" 之间添加
pre_process钩子,支持具体实现灵活增强流程,而无需修改模板方法本身。 - 数据共享的安全性 :模板框架与具体实现共享的数据(如结构体成员)需明确访问规则,避免具体实现修改框架依赖的关键数据(可通过
const限定或封装访问接口)。 - 错误处理的一致性:模板方法应统一错误处理逻辑(如返回码规范、日志输出格式),具体步骤通过返回值通知错误,由模板方法统一处理,确保错误行为的一致性。
六、补充说明
- 模板方法模式与策略模式的区别:模板方法模式通过继承(或结构体组合)复用流程框架 ,强调 "流程固定、步骤可变";策略模式通过组合算法对象实现行为替换,强调 "算法独立、动态选择"。前者是 "框架驱动",后者是 "算法驱动"。
- 模板方法的变体:可实现 "钩子方法(Hook Method)",即模板中定义的可选步骤(默认空实现),具体实现可根据需要重写,例如在测试框架中添加
pre_run和post_run钩子。 - 适用场景:流程标准化的场景(如协议交互、设备初始化)、多实现共享框架的场景(如文件系统、驱动程序)、需要保证流程一致性的场景(如测试用例、事务处理)。
通过模板方法模式,C 语言程序(尤其是 Linux 内核)能够高效复用固定流程框架,同时允许具体步骤的灵活定制,在保证系统一致性的前提下降低代码冗余,是构建标准化、可扩展系统的核心技术。内核中大量核心组件采用该模式,体现了 "框架复用、细节定制" 的设计哲学。
|---------------------|
| 点击下面关注,获取最新最全分享,不迷路 |