设计模式之建造者模式在 C 语言中的应用(含 Linux 内核实例)

文章目录

        • 一、建造者模式的定义与核心价值
        • [二、C 语言实现建造者模式的核心思路](#二、C 语言实现建造者模式的核心思路)
        • [三、5 个实例](#三、5 个实例)
          • [实例 1:基础建造者模式(汽车构建)](#实例 1:基础建造者模式(汽车构建))
          • [实例 2:配置文件构建(键值对配置)](#实例 2:配置文件构建(键值对配置))
          • [实例 3:网络请求构建(HTTP 请求组装)](#实例 3:网络请求构建(HTTP 请求组装))
          • [实例 4:硬件配置构建(嵌入式设备配置)](#实例 4:硬件配置构建(嵌入式设备配置))
          • [实例 5:内核风格建造者(内核模块参数构建)](#实例 5:内核风格建造者(内核模块参数构建))
        • [四、Linux 内核中的建造者模式应用](#四、Linux 内核中的建造者模式应用)
        • 五、实现注意事项
        • 六、补充说明
一、建造者模式的定义与核心价值

建造者模式(Builder Pattern)是一种创建型设计模式,其核心是将复杂对象的构建过程与对象表示分离------ 通过一个 "建造者" 角色分步构建对象的各个组件,再由 "指挥者" 角色统一控制构建流程,最终生成独立于构建过程的复杂对象。

存在的意义:当一个对象包含多个组件(如汽车包含发动机、底盘、车身),且组件的构建顺序或细节复杂时,直接在构造函数中构建会导致代码臃肿、耦合紧密(修改一个组件需修改整个构造逻辑)。建造者模式通过分步构建 + 流程控制,使复杂对象的构建更灵活、可维护。

解决的问题

  • 复杂对象的构建逻辑与对象本身强耦合,构造函数庞大难维护;
  • 同一对象需多种不同表示(如 "基础版汽车""豪华版汽车"),需重复编写大量相似构建代码;
  • 构建过程需严格遵循特定顺序(如先装底盘再装车身),直接编码易遗漏或打乱顺序。
二、C 语言实现建造者模式的核心思路

C 语言通过结构体封装建造者与产品 +函数指针定义构建接口实现模式,核心角色分工:

  1. 产品(Product):待构建的复杂对象(如汽车、配置文件),包含多个组件;
  2. 建造者(Builder) :定义分步构建组件的接口(如build_chassisbuild_engine),并持有产品实例;
  3. 具体建造者(Concrete Builder):实现建造者接口,完成具体组件的构建(如 "基础版汽车建造者""豪华版汽车建造者");
  4. 指挥者(Director) :定义构建流程(如 "先构建底盘→再构建发动机→最后构建车身"),调用建造者的接口完成构建,不依赖具体建造者。
三、5 个实例
实例 1:基础建造者模式(汽车构建)

模拟汽车的构建过程,支持 "基础版" 和 "豪华版" 两种汽车,通过建造者分步构建底盘、发动机、车身,指挥者控制流程。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// 1. 产品:汽车(包含多个组件)
typedef struct {
    char chassis[32];  // 底盘
    char engine[32];   // 发动机
    char body[32];     // 车身
    bool has_sunroof;  // 是否有天窗(豪华版专属)
} Car;

// 2. 建造者接口:定义分步构建方法
typedef struct {
    Car* car; // 持有待构建的产品
    // 分步构建接口
    void (*build_chassis)(struct CarBuilder* self);
    void (*build_engine)(struct CarBuilder* self);
    void (*build_body)(struct CarBuilder* self);
    // 获取构建完成的产品
    Car* (*get_car)(struct CarBuilder* self);
    // 重置建造者(用于重新构建)
    void (*reset)(struct CarBuilder* self);
} CarBuilder;

// 3. 具体建造者1:基础版汽车建造者
typedef struct {
    CarBuilder base; // 继承建造者接口
} BasicCarBuilder;

// 基础版底盘构建
static void basic_build_chassis(CarBuilder* self) {
    strncpy(self->car->chassis, "Basic Chassis", sizeof(self->car->chassis)-1);
    printf("Built basic chassis\n");
}

// 基础版发动机构建
static void basic_build_engine(CarBuilder* self) {
    strncpy(self->car->engine, "1.5L Engine", sizeof(self->car->engine)-1);
    printf("Built basic engine\n");
}

// 基础版车身构建(无天窗)
static void basic_build_body(CarBuilder* self) {
    strncpy(self->car->body, "Basic Body", sizeof(self->car->body)-1);
    self->car->has_sunroof = false;
    printf("Built basic body (no sunroof)\n");
}

// 获取基础版汽车
static Car* basic_get_car(CarBuilder* self) {
    Car* result = self->car;
    self->car = NULL; // 释放产品所有权
    return result;
}

// 重置基础版建造者
static void basic_reset(CarBuilder* self) {
    if (self->car) free(self->car);
    self->car = malloc(sizeof(Car));
    memset(self->car, 0, sizeof(Car));
}

// 初始化基础版建造者
void init_basic_car_builder(BasicCarBuilder* builder) {
    builder->base.car = malloc(sizeof(Car));
    memset(builder->base.car, 0, sizeof(Car));
    // 绑定具体构建方法
    builder->base.build_chassis = basic_build_chassis;
    builder->base.build_engine = basic_build_engine;
    builder->base.build_body = basic_build_body;
    builder->base.get_car = basic_get_car;
    builder->base.reset = basic_reset;
}

// 具体建造者2:豪华版汽车建造者
typedef struct {
    CarBuilder base; // 继承建造者接口
} LuxuryCarBuilder;

// 豪华版底盘构建
static void luxury_build_chassis(CarBuilder* self) {
    strncpy(self->car->chassis, "Luxury Chassis", sizeof(self->car->chassis)-1);
    printf("Built luxury chassis\n");
}

// 豪华版发动机构建
static void luxury_build_engine(CarBuilder* self) {
    strncpy(self->car->engine, "3.0L Turbo Engine", sizeof(self->car->engine)-1);
    printf("Built luxury engine\n");
}

// 豪华版车身构建(带天窗)
static void luxury_build_body(CarBuilder* self) {
    strncpy(self->car->body, "Luxury Body", sizeof(self->car->body)-1);
    self->car->has_sunroof = true;
    printf("Built luxury body (with sunroof)\n");
}

// 获取豪华版汽车(复用基础版的get_car逻辑)
static Car* luxury_get_car(CarBuilder* self) {
    return basic_get_car(self);
}

// 重置豪华版建造者(复用基础版的reset逻辑)
static void luxury_reset(CarBuilder* self) {
    basic_reset(self);
}

// 初始化豪华版建造者
void init_luxury_car_builder(LuxuryCarBuilder* builder) {
    builder->base.car = malloc(sizeof(Car));
    memset(builder->base.car, 0, sizeof(Car));
    // 绑定具体构建方法
    builder->base.build_chassis = luxury_build_chassis;
    builder->base.build_engine = luxury_build_engine;
    builder->base.build_body = luxury_build_body;
    builder->base.get_car = luxury_get_car;
    builder->base.reset = luxury_reset;
}

// 4. 指挥者:控制汽车构建流程(先底盘→再发动机→最后车身)
typedef struct {
    void (*construct_car)(struct CarDirector* self, CarBuilder* builder);
} CarDirector;

static void construct_car(CarDirector* self, CarBuilder* builder) {
    (void)self;
    printf("\n=== Starting car construction ===\n");
    builder->reset(builder);       // 先重置建造者
    builder->build_chassis(builder); // 步骤1:构建底盘
    builder->build_engine(builder);  // 步骤2:构建发动机
    builder->build_body(builder);    // 步骤3:构建车身
    printf("=== Construction completed ===\n");
}

// 初始化指挥者
void init_car_director(CarDirector* director) {
    director->construct_car = construct_car;
}

// 辅助函数:打印汽车信息
void print_car(const Car* car) {
    printf("\nCar Info:\n");
    printf("Chassis: %s\n", car->chassis);
    printf("Engine: %s\n", car->engine);
    printf("Body: %s\n", car->body);
    printf("Sunroof: %s\n", car->has_sunroof ? "Yes" : "No");
}

// 客户端使用
int main() {
    // 初始化指挥者
    CarDirector director;
    init_car_director(&director);

    // 1. 构建基础版汽车
    BasicCarBuilder basic_builder;
    init_basic_car_builder(&basic_builder);
    director.construct_car(&director, &basic_builder.base);
    Car* basic_car = basic_builder.base.get_car(&basic_builder.base);
    print_car(basic_car);

    // 2. 构建豪华版汽车
    LuxuryCarBuilder luxury_builder;
    init_luxury_car_builder(&luxury_builder);
    director.construct_car(&director, &luxury_builder.base);
    Car* luxury_car = luxury_builder.base.get_car(&luxury_builder.base);
    print_car(luxury_car);

    // 释放资源
    free(basic_car);
    free(luxury_car);
    return 0;
}

以上的代码运行结果为

复制代码
=== Starting car construction ===
Built basic chassis
Built basic engine
Built basic body (no sunroof)
=== Construction completed ===

Car Info:
Chassis: Basic Chassis
Engine: 1.5L Engine
Body: Basic Body
Sunroof: No

=== Starting car construction ===
Built luxury chassis
Built luxury engine
Built luxury body (with sunroof)
=== Construction completed ===

Car Info:
Chassis: Luxury Chassis
Engine: 3.0L Turbo Engine
Body: Luxury Body
Sunroof: Yes

其UML图例为

即指挥者CarDirector定义固定构建流程(底盘→发动机→车身),具体建造者BasicCarBuilderLuxuryCarBuilder实现不同组件的构建逻辑。新增 "运动版汽车" 只需添加新建造者,无需修改指挥者或产品代码,符合 "开闭原则"。

实例 2:配置文件构建(键值对配置)

模拟配置文件的构建,支持分步添加键值对、设置注释,最终生成完整的配置字符串,适合需要灵活组装配置的场景。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 1. 产品:配置文件(存储键值对和注释)
#define MAX_KV 20  // 最大键值对数量
#define MAX_COMMENT 100 // 最大注释长度
#define MAX_CONTENT 512 // 最大配置内容长度
typedef struct {
    char comments[MAX_COMMENT];
    char keys[MAX_KV][32];
    char vals[MAX_KV][64];
    int kv_count;
    char content[MAX_CONTENT]; // 最终生成的配置字符串
} ConfigFile;

// 2. 建造者接口:配置文件构建
typedef struct {
    ConfigFile* config;
    void (*add_comment)(struct ConfigBuilder* self, const char* comment);
    void (*add_kv)(struct ConfigBuilder* self, const char* key, const char* val);
    void (*generate_content)(struct ConfigBuilder* self); // 生成最终配置
    ConfigFile* (*get_config)(struct ConfigBuilder* self);
    void (*reset)(struct ConfigBuilder* self);
} ConfigBuilder;

// 3. 具体建造者:INI格式配置建造者
typedef struct {
    ConfigBuilder base;
} IniConfigBuilder;

// 添加注释
static void ini_add_comment(ConfigBuilder* self, const char* comment) {
    strncpy(self->config->comments, comment, sizeof(self->config->comments)-1);
    printf("Added comment: %s\n", comment);
}

// 添加键值对
static void ini_add_kv(ConfigBuilder* self, const char* key, const char* val) {
    if (self->config->kv_count >= MAX_KV) {
        printf("Max key-value pairs reached\n");
        return;
    }
    strncpy(self->config->keys[self->config->kv_count], key, sizeof(self->config->keys[0])-1);
    strncpy(self->config->vals[self->config->kv_count], val, sizeof(self->config->vals[0])-1);
    self->config->kv_count++;
    printf("Added KV: %s=%s\n", key, val);
}

// 生成INI格式配置内容
static void ini_generate_content(ConfigBuilder* self) {
    ConfigFile* cfg = self->config;
    // 清空内容
    cfg->content[0] = '\0';
    // 追加注释
    if (cfg->comments[0] != '\0') {
        snprintf(cfg->content, MAX_CONTENT, "; %s\n", cfg->comments);
    }
    // 追加键值对
    for (int i = 0; i < cfg->kv_count; i++) {
        strncat(cfg->content, cfg->keys[i], MAX_CONTENT - strlen(cfg->content) - 1);
        strncat(cfg->content, " = ", MAX_CONTENT - strlen(cfg->content) - 1);
        strncat(cfg->content, cfg->vals[i], MAX_CONTENT - strlen(cfg->content) - 1);
        strncat(cfg->content, "\n", MAX_CONTENT - strlen(cfg->content) - 1);
    }
    printf("Generated INI content\n");
}

// 获取配置文件
static ConfigFile* ini_get_config(ConfigBuilder* self) {
    ConfigFile* result = self->config;
    self->config = NULL;
    return result;
}

// 重置建造者
static void ini_reset(ConfigBuilder* self) {
    if (self->config) free(self->config);
    self->config = malloc(sizeof(ConfigFile));
    memset(self->config, 0, sizeof(ConfigFile));
}

// 初始化INI建造者
void init_ini_builder(IniConfigBuilder* builder) {
    builder->base.config = malloc(sizeof(ConfigFile));
    memset(builder->base.config, 0, sizeof(ConfigFile));
    builder->base.add_comment = ini_add_comment;
    builder->base.add_kv = ini_add_kv;
    builder->base.generate_content = ini_generate_content;
    builder->base.get_config = ini_get_config;
    builder->base.reset = ini_reset;
}

// 4. 指挥者:配置文件构建流程(注释→键值对→生成内容)
typedef struct {
    void (*construct_config)(struct ConfigDirector* self, ConfigBuilder* builder, 
                             const char* comment, const char* keys[], const char* vals[], int kv_count);
} ConfigDirector;

static void construct_config(ConfigDirector* self, ConfigBuilder* builder, 
                             const char* comment, const char* keys[], const char* vals[], int kv_count) {
    (void)self;
    printf("\n=== Starting config construction ===\n");
    builder->reset(builder);
    if (comment) builder->add_comment(builder, comment); // 步骤1:添加注释
    for (int i = 0; i < kv_count; i++) {                 // 步骤2:添加键值对
        builder->add_kv(builder, keys[i], vals[i]);
    }
    builder->generate_content(builder);                  // 步骤3:生成配置
    printf("=== Config construction completed ===\n");
}

void init_config_director(ConfigDirector* director) {
    director->construct_config = construct_config;
}

// 客户端使用
int main() {
    // 初始化指挥者
    ConfigDirector director;
    init_config_director(&director);

    // 初始化INI建造者
    IniConfigBuilder ini_builder;
    init_ini_builder(&ini_builder);

    // 准备配置数据
    const char* comment = "App Config File";
    const char* keys[] = {"port", "timeout", "log_level"};
    const char* vals[] = {"8080", "30", "info"};
    int kv_count = sizeof(keys)/sizeof(keys[0]);

    // 构建配置文件
    director.construct_config(&director, &ini_builder.base, comment, keys, vals, kv_count);
    ConfigFile* config = ini_builder.base.get_config(&ini_builder.base);

    // 打印结果
    printf("\nFinal INI Config:\n%s", config->content);

    // 释放资源
    free(config);
    return 0;
}

以上代码运行结果

复制代码
=== Starting config construction ===
Added comment: App Config File
Added KV: port=8080
Added KV: timeout=30
Added KV: log_level=info
Generated INI content
=== Config construction completed ===

Final INI Config:
; App Config File
port = 8080
timeout = 30
log_level = info

其UML为

即指挥者按 "注释→键值对→生成内容" 的流程构建配置文件,建造者负责具体的 INI 格式组装。若需支持 JSON 格式,只需添加JsonConfigBuilder,复用指挥者流程,体现 "流程与实现分离" 的核心思想。

实例 3:网络请求构建(HTTP 请求组装)

模拟 HTTP 请求的构建,支持设置 URL、请求方法、请求头、请求体,最终生成可发送的请求字符串。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 1. 产品:HTTP请求
#define MAX_HEADER 10 // 最大请求头数量
#define MAX_BODY 256  // 最大请求体长度
typedef struct {
    char method[16];   // GET/POST
    char url[128];     // 请求URL
    char headers[MAX_HEADER][64]; // 请求头(如"Host: example.com")
    int header_count;
    char body[MAX_BODY]; // 请求体
    char request_str[512]; // 最终请求字符串
} HttpRequest;

// 2. 建造者接口:HTTP请求构建
typedef struct {
    HttpRequest* req;
    void (*set_method)(struct HttpRequestBuilder* self, const char* method);
    void (*set_url)(struct HttpRequestBuilder* self, const char* url);
    void (*add_header)(struct HttpRequestBuilder* self, const char* key, const char* val);
    void (*set_body)(struct HttpRequestBuilder* self, const char* body);
    void (*build_request)(struct HttpRequestBuilder* self); // 组装请求
    HttpRequest* (*get_request)(struct HttpRequestBuilder* self);
    void (*reset)(struct HttpRequestBuilder* self);
} HttpRequestBuilder;

// 3. 具体建造者:HTTP请求建造者(无变体,专注组装逻辑)
typedef struct {
    HttpRequestBuilder base;
} ConcreteHttpRequestBuilder;

// 设置请求方法
static void set_method(HttpRequestBuilder* self, const char* method) {
    strncpy(self->req->method, method, sizeof(self->req->method)-1);
    printf("Set method: %s\n", method);
}

// 设置请求URL
static void set_url(HttpRequestBuilder* self, const char* url) {
    strncpy(self->req->url, url, sizeof(self->req->url)-1);
    printf("Set URL: %s\n", url);
}

// 添加请求头
static void add_header(HttpRequestBuilder* self, const char* key, const char* val) {
    if (self->req->header_count >= MAX_HEADER) {
        printf("Max headers reached\n");
        return;
    }
    snprintf(self->req->headers[self->req->header_count], sizeof(self->req->headers[0]), 
             "%s: %s", key, val);
    self->req->header_count++;
    printf("Added header: %s: %s\n", key, val);
}

// 设置请求体
static void set_body(HttpRequestBuilder* self, const char* body) {
    strncpy(self->req->body, body, sizeof(self->req->body)-1);
    printf("Set body: %s\n", body);
}

// 组装HTTP请求字符串
static void build_request(HttpRequestBuilder* self) {
    HttpRequest* req = self->req;
    req->request_str[0] = '\0';
    // 组装请求行(Method URL HTTP/1.1)
    snprintf(req->request_str, sizeof(req->request_str), "%s %s HTTP/1.1\n", req->method, req->url);
    // 组装请求头
    for (int i = 0; i < req->header_count; i++) {
        strncat(req->request_str, req->headers[i], sizeof(req->request_str)-strlen(req->request_str)-1);
        strncat(req->request_str, "\n", sizeof(req->request_str)-strlen(req->request_str)-1);
    }
    // 组装请求体(空行分隔头和体)
    if (req->body[0] != '\0') {
        strncat(req->request_str, "\n", sizeof(req->request_str)-strlen(req->request_str)-1);
        strncat(req->request_str, req->body, sizeof(req->request_str)-strlen(req->request_str)-1);
    }
    printf("Built HTTP request\n");
}

// 获取请求
static HttpRequest* get_request(HttpRequestBuilder* self) {
    HttpRequest* result = self->req;
    self->req = NULL;
    return result;
}

// 重置建造者
static void req_reset(HttpRequestBuilder* self) {
    if (self->req) free(self->req);
    self->req = malloc(sizeof(HttpRequest));
    memset(self->req, 0, sizeof(HttpRequest));
}

// 初始化HTTP请求建造者
void init_http_builder(ConcreteHttpRequestBuilder* builder) {
    builder->base.req = malloc(sizeof(HttpRequest));
    memset(builder->base.req, 0, sizeof(HttpRequest));
    builder->base.set_method = set_method;
    builder->base.set_url = set_url;
    builder->base.add_header = add_header;
    builder->base.set_body = set_body;
    builder->base.build_request = build_request;
    builder->base.get_request = get_request;
    builder->base.reset = req_reset;
}

// 4. 指挥者:HTTP GET/POST请求流程
typedef struct {
    void (*construct_get)(struct HttpDirector* self, HttpRequestBuilder* builder, const char* url, const char* host);
    void (*construct_post)(struct HttpDirector* self, HttpRequestBuilder* builder, const char* url, const char* host, const char* body);
} HttpDirector;

// 构建GET请求(无请求体)
static void construct_get(HttpDirector* self, HttpRequestBuilder* builder, const char* url, const char* host) {
    (void)self;
    printf("\n=== Starting GET request construction ===\n");
    builder->reset(builder);
    builder->set_method(builder, "GET");    // 步骤1:方法
    builder->set_url(builder, url);        // 步骤2:URL
    builder->add_header(builder, "Host", host); // 步骤3:请求头
    builder->build_request(builder);       // 步骤4:组装
    printf("=== GET request completed ===\n");
}

// 构建POST请求(带请求体)
static void construct_post(HttpDirector* self, HttpRequestBuilder* builder, const char* url, const char* host, const char* body) {
    (void)self;
    printf("\n=== Starting POST request construction ===\n");
    builder->reset(builder);
    builder->set_method(builder, "POST");   // 步骤1:方法
    builder->set_url(builder, url);        // 步骤2:URL
    builder->add_header(builder, "Host", host); // 步骤3:请求头
    builder->add_header(builder, "Content-Type", "application/json");
    builder->set_body(builder, body);      // 步骤4:请求体
    builder->build_request(builder);       // 步骤5:组装
    printf("=== POST request completed ===\n");
}

// 初始化HTTP指挥者
void init_http_director(HttpDirector* director) {
    director->construct_get = construct_get;
    director->construct_post = construct_post;
}

// 客户端使用
int main() {
    // 初始化指挥者和建造者
    HttpDirector director;
    init_http_director(&director);
    ConcreteHttpRequestBuilder builder;
    init_http_builder(&builder);

    // 1. 构建GET请求
    director.construct_get(&director, &builder.base, "/index.html", "example.com");
    HttpRequest* get_req = builder.base.get_request(&builder.base);
    printf("\nFinal GET Request:\n%s\n", get_req->request_str);
    free(get_req);

    // 2. 构建POST请求
    const char* post_body = "{\"username\":\"test\",\"password\":\"123\"}";
    director.construct_post(&director, &builder.base, "/login", "example.com", post_body);
    HttpRequest* post_req = builder.base.get_request(&builder.base);
    printf("\nFinal POST Request:\n%s\n", post_req->request_str);
    free(post_req);

    return 0;
}

以上代码执行结果如下

复制代码
=== Starting GET request construction ===
Set method: GET
Set URL: /index.html
Added header: Host: example.com
Built HTTP request
=== GET request completed ===

Final GET Request:
GET /index.html HTTP/1.1
Host: example.com


=== Starting POST request construction ===
Set method: POST
Set URL: /login
Added header: Host: example.com
Added header: Content-Type: application/json
Set body: {"username":"test","password":"123"}
Built HTTP request
=== POST request completed ===

Final POST Request:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json

{"username":"test","password":"123"}

其UML图例为

即指挥者针对 GET/POST 请求提供不同构建流程(POST 多一步 "设置请求体"),建造者负责具体的 HTTP 格式组装。新增 PUT/DELETE 请求只需在指挥者中添加对应流程,无需修改建造者核心逻辑。

实例 4:硬件配置构建(嵌入式设备配置)

模拟嵌入式设备的硬件配置(如 GPIO、UART、SPI),通过建造者分步配置硬件参数,指挥者控制初始化顺序。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>

// 1. 产品:硬件配置
typedef struct {
    // GPIO配置
    uint8_t gpio_pin;
    bool gpio_output; // true=输出,false=输入
    // UART配置
    uint32_t uart_baud;
    uint8_t uart_pin_tx;
    uint8_t uart_pin_rx;
    // SPI配置
    uint32_t spi_clk;
    bool spi_master; // true=主机,false=从机
} HardwareConfig;

// 2. 建造者接口:硬件配置构建
typedef struct {
    HardwareConfig* config;
    void (*config_gpio)(struct HardwareBuilder* self, uint8_t pin, bool is_output);
    void (*config_uart)(struct HardwareBuilder* self, uint32_t baud, uint8_t tx_pin, uint8_t rx_pin);
    void (*config_spi)(struct HardwareBuilder* self, uint32_t clk, bool is_master);
    HardwareConfig* (*get_config)(struct HardwareBuilder* self);
    void (*reset)(struct HardwareBuilder* self);
} HardwareBuilder;

// 3. 具体建造者:嵌入式硬件建造者
typedef struct {
    HardwareBuilder base;
} EmbeddedHardwareBuilder;

// 配置GPIO
static void config_gpio(HardwareBuilder* self, uint8_t pin, bool is_output) {
    self->config->gpio_pin = pin;
    self->config->gpio_output = is_output;
    printf("Configured GPIO: Pin=%d, Mode=%s\n", pin, is_output ? "Output" : "Input");
}

// 配置UART
static void config_uart(HardwareBuilder* self, uint32_t baud, uint8_t tx_pin, uint8_t rx_pin) {
    self->config->uart_baud = baud;
    self->config->uart_pin_tx = tx_pin;
    self->config->uart_pin_rx = rx_pin;
    printf("Configured UART: Baud=%d, TX=%d, RX=%d\n", baud, tx_pin, rx_pin);
}

// 配置SPI
static void config_spi(HardwareBuilder* self, uint32_t clk, bool is_master) {
    self->config->spi_clk = clk;
    self->config->spi_master = is_master;
    printf("Configured SPI: Clk=%dHz, Mode=%s\n", clk, is_master ? "Master" : "Slave");
}

// 获取配置
static HardwareConfig* get_config(HardwareBuilder* self) {
    HardwareConfig* result = self->config;
    self->config = NULL;
    return result;
}

// 重置建造者
static void hw_reset(HardwareBuilder* self) {
    if (self->config) free(self->config);
    self->config = malloc(sizeof(HardwareConfig));
    memset(self->config, 0, sizeof(HardwareConfig));
}

// 初始化硬件建造者
void init_embedded_builder(EmbeddedHardwareBuilder* builder) {
    builder->base.config = malloc(sizeof(HardwareConfig));
    memset(builder->base.config, 0, sizeof(HardwareConfig));
    builder->base.config_gpio = config_gpio;
    builder->base.config_uart = config_uart;
    builder->base.config_spi = config_spi;
    builder->base.get_config = get_config;
    builder->base.reset = hw_reset;
}

// 4. 指挥者:硬件初始化流程(GPIO→UART→SPI)
typedef struct {
    void (*construct_hw)(struct HardwareDirector* self, HardwareBuilder* builder,
                         uint8_t gpio_pin, bool gpio_output,
                         uint32_t uart_baud, uint8_t uart_tx, uint8_t uart_rx,
                         uint32_t spi_clk, bool spi_master);
} HardwareDirector;

static void construct_hw(HardwareDirector* self, HardwareBuilder* builder,
                         uint8_t gpio_pin, bool gpio_output,
                         uint32_t uart_baud, uint8_t uart_tx, uint8_t uart_rx,
                         uint32_t spi_clk, bool spi_master) {
    (void)self;
    printf("\n=== Starting hardware configuration ===\n");
    builder->reset(builder);
    builder->config_gpio(builder, gpio_pin, gpio_output); // 步骤1:GPIO
    builder->config_uart(builder, uart_baud, uart_tx, uart_rx); // 步骤2:UART
    builder->config_spi(builder, spi_clk, spi_master);     // 步骤3:SPI
    printf("=== Hardware configuration completed ===\n");
}

void init_hw_director(HardwareDirector* director) {
    director->construct_hw = construct_hw;
}

// 客户端使用
int main() {
    // 初始化指挥者和建造者
    HardwareDirector director;
    init_hw_director(&director);
    EmbeddedHardwareBuilder builder;
    init_embedded_builder(&builder);

    // 构建硬件配置(GPIO10输出,UART115200波特率,SPI 1MHz主机)
    director.construct_hw(&director, &builder.base,
                          10, true,    // GPIO
                          115200, 11, 12, // UART
                          1000000, true); // SPI

    // 获取并打印配置
    HardwareConfig* hw_cfg = builder.base.get_config(&builder.base);
    printf("\nFinal Hardware Config:\n");
    printf("GPIO: Pin=%d, Output=%d\n", hw_cfg->gpio_pin, hw_cfg->gpio_output);
    printf("UART: Baud=%d, TX=%d, RX=%d\n", hw_cfg->uart_baud, hw_cfg->uart_pin_tx, hw_cfg->uart_pin_rx);
    printf("SPI: Clk=%dHz, Master=%d\n", hw_cfg->spi_clk, hw_cfg->spi_master);

    free(hw_cfg);
    return 0;
}

以上代码执行结果如下

复制代码
=== Starting hardware configuration ===
Configured GPIO: Pin=10, Mode=Output
Configured UART: Baud=115200, TX=11, RX=12
Configured SPI: Clk=1000000Hz, Mode=Master
=== Hardware configuration completed ===

Final Hardware Config:
GPIO: Pin=10, Output=1
UART: Baud=115200, TX=11, RX=12
SPI: Clk=1000000Hz, Master=1

其UML图例为

即,硬件初始化需严格遵循顺序(如先配置 GPIO 再配置外设),指挥者确保流程正确,建造者封装具体硬件的配置细节。更换硬件平台时,只需修改建造者的配置逻辑,指挥者流程可复用。

实例 5:内核风格建造者(内核模块参数构建)

模拟 Linux 内核模块参数的构建,通过建造者分步添加参数(整数、字符串、布尔值),指挥者控制参数注册流程,符合内核驱动开发的设计思想。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// 1. 产品:内核模块参数集合
#define MAX_PARAMS 5
typedef enum { PARAM_INT, PARAM_STR, PARAM_BOOL } ParamType;
typedef struct {
    char name[32];
    ParamType type;
    union {
        int int_val;
        char str_val[64];
        bool bool_val;
    } value;
} ModuleParam;

typedef struct {
    ModuleParam params[MAX_PARAMS];
    int param_count;
    char module_name[32]; // 模块名称
} ModuleParams;

// 2. 建造者接口:模块参数构建
typedef struct {
    ModuleParams* params;
    void (*add_int_param)(struct ModuleParamBuilder* self, const char* name, int val);
    void (*add_str_param)(struct ModuleParamBuilder* self, const char* name, const char* val);
    void (*add_bool_param)(struct ModuleParamBuilder* self, const char* name, bool val);
    ModuleParams* (*get_params)(struct ModuleParamBuilder* self);
    void (*reset)(struct ModuleParamBuilder* self);
} ModuleParamBuilder;

// 3. 具体建造者:内核模块参数建造者
typedef struct {
    ModuleParamBuilder base;
} KernelModuleParamBuilder;

// 添加整数参数
static void add_int_param(ModuleParamBuilder* self, const char* name, int val) {
    if (self->params->param_count >= MAX_PARAMS) {
        printf("Max module params reached\n");
        return;
    }
    ModuleParam* param = &self->params->params[self->params->param_count++];
    strncpy(param->name, name, sizeof(param->name)-1);
    param->type = PARAM_INT;
    param->value.int_val = val;
    printf("Added int param: %s=%d\n", name, val);
}

// 添加字符串参数
static void add_str_param(ModuleParamBuilder* self, const char* name, const char* val) {
    if (self->params->param_count >= MAX_PARAMS) {
        printf("Max module params reached\n");
        return;
    }
    ModuleParam* param = &self->params->params[self->params->param_count++];
    strncpy(param->name, name, sizeof(param->name)-1);
    param->type = PARAM_STR;
    strncpy(param->value.str_val, val, sizeof(param->value.str_val)-1);
    printf("Added str param: %s=%s\n", name, val);
}

// 添加布尔参数
static void add_bool_param(ModuleParamBuilder* self, const char* name, bool val) {
    if (self->params->param_count >= MAX_PARAMS) {
        printf("Max module params reached\n");
        return;
    }
    ModuleParam* param = &self->params->params[self->params->param_count++];
    strncpy(param->name, name, sizeof(param->name)-1);
    param->type = PARAM_BOOL;
    param->value.bool_val = val;
    printf("Added bool param: %s=%s\n", name, val ? "true" : "false");
}

// 获取参数集合
static ModuleParams* get_params(ModuleParamBuilder* self) {
    ModuleParams* result = self->params;
    self->params = NULL;
    return result;
}

// 重置建造者
static void param_reset(ModuleParamBuilder* self) {
    if (self->params) free(self->params);
    self->params = malloc(sizeof(ModuleParams));
    memset(self->params, 0, sizeof(ModuleParams));
}

// 初始化内核参数建造者
void init_kernel_param_builder(KernelModuleParamBuilder* builder, const char* module_name) {
    builder->base.params = malloc(sizeof(ModuleParams));
    memset(builder->base.params, 0, sizeof(ModuleParams));
    strncpy(builder->base.params->module_name, module_name, sizeof(builder->base.params->module_name)-1);
    builder->base.add_int_param = add_int_param;
    builder->base.add_str_param = add_str_param;
    builder->base.add_bool_param = add_bool_param;
    builder->base.get_params = get_params;
    builder->base.reset = param_reset;
}

// 4. 指挥者:内核模块参数构建流程(整数→字符串→布尔)
typedef struct {
    void (*construct_module_params)(struct ModuleDirector* self, ModuleParamBuilder* builder,
                                    const char* int_names[], int int_vals[], int int_count,
                                    const char* str_names[], const char* str_vals[], int str_count,
                                    const char* bool_names[], bool bool_vals[], int bool_count);
} ModuleDirector;

static void construct_module_params(ModuleDirector* self, ModuleParamBuilder* builder,
                                    const char* int_names[], int int_vals[], int int_count,
                                    const char* str_names[], const char* str_vals[], int str_count,
                                    const char* bool_names[], bool bool_vals[], int bool_count) {
    (void)self;
    printf("\n=== Starting module params construction ===\n");
    builder->reset(builder);
    // 步骤1:添加整数参数
    for (int i = 0; i < int_count; i++) {
        builder->add_int_param(builder, int_names[i], int_vals[i]);
    }
    // 步骤2:添加字符串参数
    for (int i = 0; i < str_count; i++) {
        builder->add_str_param(builder, str_names[i], str_vals[i]);
    }
    // 步骤3:添加布尔参数
    for (int i = 0; i < bool_count; i++) {
        builder->add_bool_param(builder, bool_names[i], bool_vals[i]);
    }
    printf("=== Module params construction completed ===\n");
}

void init_module_director(ModuleDirector* director) {
    director->construct_module_params = construct_module_params;
}

// 客户端使用(模拟内核模块参数注册)
int main() {
    // 初始化指挥者
    ModuleDirector director;
    init_module_director(&director);

    // 初始化建造者(模块名:"net_driver")
    KernelModuleParamBuilder builder;
    init_kernel_param_builder(&builder, "net_driver");

    // 准备参数数据
    const char* int_names[] = {"port", "timeout"};
    int int_vals[] = {8080, 30};
    int int_count = sizeof(int_names)/sizeof(int_names[0]);

    const char* str_names[] = {"ifname"};
    const char* str_vals[] = {"eth0"};
    int str_count = sizeof(str_names)/sizeof(str_names[0]);

    const char* bool_names[] = {"debug"};
    bool bool_vals[] = {true};
    int bool_count = sizeof(bool_names)/sizeof(bool_names[0]);

    // 构建模块参数
    director.construct_module_params(&director, &builder.base,
                                    int_names, int_vals, int_count,
                                    str_names, str_vals, str_count,
                                    bool_names, bool_vals, bool_count);

    // 获取并打印参数
    ModuleParams* params = builder.base.get_params(&builder.base);
    printf("\nFinal Module Params (Module: %s):\n", params->module_name);
    for (int i = 0; i < params->param_count; i++) {
        ModuleParam* p = &params->params[i];
        printf("%s: ", p->name);
        switch (p->type) {
            case PARAM_INT: printf("%d\n", p->value.int_val); break;
            case PARAM_STR: printf("%s\n", p->value.str_val); break;
            case PARAM_BOOL: printf("%s\n", p->value.bool_val ? "true" : "false"); break;
        }
    }

    free(params);
    return 0;
}

以上代码执行结果如下

复制代码
=== Starting module params construction ===
Added int param: port=8080
Added int param: timeout=30
Added str param: ifname=eth0
Added bool param: debug=true
=== Module params construction completed ===

Final Module Params (Module: ):
port: 8080
timeout: 30
ifname: eth0
debug: true

其UML图例如下

即模拟 Linux 内核模块参数的注册流程,指挥者按 "整数→字符串→布尔" 的顺序添加参数,建造者封装参数的类型和值存储。内核中实际的module_param宏本质也是一种简化的建造者模式,通过宏定义分步注册参数,最终统一纳入内核参数管理系统。

四、Linux 内核中的建造者模式应用
  1. 内核对象构建(kobjectkset :内核设备模型中,kobject(内核对象)的构建需设置名称、父对象、属性集等组件,kobject_init_and_add等函数作为 "建造者" 分步初始化组件,kset作为 "指挥者" 统一管理对象的注册流程,确保对象正确加入内核对象层级。
  2. 网络数据包构建(sk_buffsk_buff(套接字缓冲区)是复杂的网络对象,包含数据区、协议头、引用计数等组件。内核通过alloc_skb(分配内存)、skb_reserve(预留头空间)、skb_put(添加数据)等 "建造者函数" 分步构建数据包,dev_queue_xmit等函数作为 "指挥者" 控制数据包的最终发送流程。
  3. 文件系统inode构建inode(索引节点)包含文件类型、权限、大小、数据块指针等组件。文件系统(如 ext4)通过ext4_iget等函数作为 "建造者",从磁盘分区读取 inode 数据、初始化权限和属性,VFS(虚拟文件系统)作为 "指挥者" 统一管理 inode 的缓存和生命周期,确保 inode 正确映射到文件描述符。
  4. 模块参数注册(module_param宏) :内核模块参数的注册需指定参数名称、类型、权限等组件,module_param系列宏(如module_int_parammodule_str_param)作为 "具体建造者",分步解析参数类型和值,内核参数管理系统作为 "指挥者",统一将参数纳入sysfs节点,支持运行时配置。
  5. 中断处理构建(irqactionirqaction(中断处理描述符)包含中断号、处理函数、触发方式等组件。驱动通过request_irq(注册中断)作为 "建造者",分步设置中断处理函数和触发方式,内核中断子系统作为 "指挥者",统一管理中断的使能、禁用和分发流程,确保中断处理正确关联硬件中断。
五、实现注意事项
  1. 组件依赖与构建顺序:复杂对象的组件可能存在依赖关系(如先有底盘才能装发动机),指挥者必须明确构建顺序,避免因顺序错误导致对象不可用;建造者需在文档中注明组件的依赖关系。
  2. 资源管理与内存安全 :建造者持有产品实例时,需确保内存分配失败时的回滚(如某组件分配失败,需释放已分配的其他组件);产品构建完成后,需通过get_product函数释放建造者对产品的所有权,避免双重释放。
  3. 建造者与产品的耦合控制:建造者应仅负责产品组件的构建,不涉及产品的业务逻辑(如汽车建造者不负责汽车驾驶);产品应提供独立的接口供外部使用,避免依赖建造者的内部实现。
  4. 简化场景的灵活适配:若对象组件简单(如仅含 2-3 个基础类型),无需严格区分建造者与指挥者,可将流程控制逻辑嵌入建造者(如合并为 "简化建造者"),避免过度设计导致代码冗余。
  5. 线程安全:多线程环境下,若多个线程同时使用同一建造者构建对象,需通过互斥锁保护建造者持有的产品实例和组件数据,避免并发修改导致的属性不一致。
六、补充说明
  • 建造者模式与工厂模式的区别:建造者模式专注于复杂对象的分步构建与流程控制 ,生成的对象组件可定制;工厂模式专注于对象类型的创建,生成的对象是完整且固定的,两者可结合使用(如工厂模式创建建造者,建造者构建产品)。
  • 建造者模式的变体:
    • 简化建造者 :无独立指挥者,建造者自身包含流程控制(如initbuild_xxxget),适合简单场景;
    • 流式建造者 :通过函数链式调用(如builder->setA()->setB()->build()),提升代码可读性,C 语言中可通过返回this指针模拟。
  • 适用场景:复杂对象构建(组件多、顺序严)、对象多变体(如基础版 / 豪华版)、嵌入式 / 内核开发(资源有限,需严格控制构建流程)、配置文件 / 网络请求等需分步组装的场景。

通过建造者模式,C 语言程序(尤其是 Linux 内核)能够高效、灵活地构建复杂对象,实现 "构建流程与对象实现分离",显著提升代码的可维护性和可扩展性,是构建高性能、高可靠性系统的核心技术之一。

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

相关推荐
lingggggaaaa23 分钟前
免杀对抗——C2远控篇&PowerShell&有无文件落地&C#参数调用&绕AMSI&ETW&去混淆特征
c语言·开发语言·笔记·学习·安全·microsoft·c#
切糕师学AI1 小时前
位带操作(Bit-Banding)是什么?
c语言·arm·嵌入式开发·cortex-m·位带操作
学习路上_write1 小时前
嵌入式系统bringup指南:软硬件调试
c语言·单片机·嵌入式硬件
say_fall1 小时前
C语言编程实战:每日一题 - day7
c语言·开发语言
小龙报2 小时前
《算法通关指南数据结构和算法篇(2)--- 链表专题》
c语言·数据结构·c++·算法·链表·学习方法·visual studio
醉颜凉2 小时前
环形房屋如何 “安全劫舍”?动态规划解题逻辑与技巧
c语言·算法·动态规划
望眼欲穿的程序猿3 小时前
Win系统Vscode+CoNan+Cmake实现调试与构建
c语言·c++·后端
星轨初途3 小时前
数据结构排序算法详解(2)——选择排序(附动图)
c语言·数据结构·经验分享·笔记·b树·算法·排序算法
合作小小程序员小小店3 小时前
游戏开发,桌面%小游戏,俄罗斯方块%demo,基于vs2022,c语言,背景音乐,easyX,无数据库,
c语言·开发语言