模板方法模式在 C 语言中的应用(含 Linux 内核实例)

文章目录

      • [模板方法模式在 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 语言通过 ** 函数指针 + 结构体组合实现模板方法模式:

  1. 定义模板框架(Template):结构体包含模板方法(固定流程的函数),以及指向抽象步骤的函数指针(需具体实现的步骤);
  2. 实现模板方法:在模板方法中按固定顺序调用抽象步骤的函数指针,构成完整算法流程;
  3. 派生具体实现:通过初始化结构体的函数指针,为抽象步骤提供具体实现,复用模板方法的流程框架。
三、 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_processreverse_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_requestrecv_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),initrun步骤因模块功能(网络 / 存储)而异,与内核中module_init/module_exit的机制一致。

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

通过模板方法模式,C 语言程序(尤其是 Linux 内核)能够高效复用固定流程框架,同时允许具体步骤的灵活定制,在保证系统一致性的前提下降低代码冗余,是构建标准化、可扩展系统的核心技术。内核中大量核心组件采用该模式,体现了 "框架复用、细节定制" 的设计哲学。

|---------------------|
| 点击下面关注,获取最新最全分享,不迷路 |

相关推荐
小温冲冲1 小时前
通俗且详细讲解模板方法模式
设计模式·模板方法模式
敲皮裤的代码1 小时前
《C语言》深入理解指针(3)
c语言
一个人旅程~3 小时前
Linux Fcitx5输入法这么难念的由来?
linux·经验分享·电脑·ai写作
开开心心就好3 小时前
一键加密隐藏视频,专属格式播放工具
java·linux·开发语言·网络·人工智能·macos
CUC-MenG3 小时前
Codeforces Round 1079 (Div. 2)A,B,C,D,E1,E2,F个人题解
c语言·开发语言·数学·算法
666HZ6663 小时前
数据结构4.0 串
c语言·数据结构·算法
小心草里有鬼3 小时前
VMware虚拟机扩容
linux·后端·centos·vim
姜行运4 小时前
【Linux】基础指令2
android·linux·服务器
比奇堡派星星4 小时前
sed命令
linux·运维·服务器·开发语言