23种设计模式介绍以及C语言实现

设计模式详解:7大原则和23种设计模式

目录

  1. 设计模式7大原则
  2. 创建型模式(5个)
  3. 结构型模式(7个)
  4. 行为型模式(11个)

设计模式7大原则

1. 单一职责原则(Single Responsibility Principle, SRP)

通俗解释: 一个类只做一件事,就像一个人只负责一个岗位。

生活例子:

  • ❌ 不好的设计:一个员工既要做会计,又要做销售,还要做客服
  • ✅ 好的设计:会计专门做账,销售专门卖货,客服专门处理客户问题

为什么重要: 如果一个人身兼数职,一旦某个职责出问题,其他职责也会受影响。代码也一样,职责单一,修改时不会影响其他功能。


2. 开闭原则(Open-Closed Principle, OCP)

通俗解释: 对扩展开放,对修改关闭。就像手机可以安装新APP(扩展),但不需要拆开手机修改硬件(关闭修改)。

生活例子:

  • 手机系统:可以安装新APP(扩展),但不需要修改系统内核(关闭修改)
  • 插座:可以插各种电器(扩展),但插座本身不需要改动(关闭修改)

为什么重要: 当需要添加新功能时,不需要修改现有代码,只需要添加新代码,降低了引入bug的风险。


3. 里氏替换原则(Liskov Substitution Principle, LSP)

通俗解释: 子类可以替换父类,而且替换后程序还能正常工作。就像"苹果是水果"一样,任何需要水果的地方,都可以用苹果。

生活例子:

  • 如果"汽车"是"交通工具"的子类,那么任何需要交通工具的地方,都可以用汽车
  • 如果"金毛"是"狗"的子类,那么任何需要狗的地方,都可以用金毛

为什么重要: 保证继承关系的正确性,子类不能破坏父类的功能。


4. 依赖倒置原则(Dependency Inversion Principle, DIP)

通俗解释: 高层模块不应该依赖低层模块,两者都应该依赖抽象。就像看电视,你依赖的是"电视接口",而不是具体的"某品牌电视"。

生活例子:

  • 充电:手机依赖的是"USB接口标准",而不是具体的"某品牌充电器"
  • 开车:司机依赖的是"方向盘、油门、刹车"这些抽象概念,而不是具体的"某品牌汽车"

为什么重要: 降低模块间的耦合,提高代码的可维护性和可扩展性。


5. 接口隔离原则(Interface Segregation Principle, ISP)

通俗解释: 不应该强迫客户端依赖它不需要的接口。就像餐厅菜单,不应该把"素食菜单"和"肉食菜单"混在一起。

生活例子:

  • ❌ 不好的设计:一个接口包含"飞行"、"游泳"、"跑步",但鸭子只需要"飞行"和"游泳"
  • ✅ 好的设计:分别定义"飞行接口"、"游泳接口"、"跑步接口",需要什么实现什么

为什么重要: 避免接口臃肿,让实现类只实现它需要的功能。


6. 迪米特法则(Law of Demeter, LoD)

通俗解释: 只和直接朋友交流,不和陌生人说话。就像你买东西,直接找售货员,而不是找售货员的老板的老板。

生活例子:

  • ❌ 不好的设计:A类通过B类获取C类,再通过C类获取D类
  • ✅ 好的设计:A类直接和B类交流,B类负责和C类、D类交流

为什么重要: 降低类之间的耦合度,提高模块的相对独立性。


7. 合成复用原则(Composite Reuse Principle, CRP)

通俗解释: 优先使用组合/聚合,而不是继承。就像组装电脑,用现成的零件组合,而不是自己造一个全新的电脑。

生活例子:

  • ❌ 不好的设计:为了用"轮子"功能,继承"汽车"类(太重了)
  • ✅ 好的设计:把"轮子"作为"自行车"的一个组成部分(组合)

为什么重要: 继承会带来强耦合,组合更灵活,可以动态改变。


创建型模式(5个)

创建型模式关注如何创建对象,让创建过程更灵活、更解耦。


1. 单例模式(Singleton Pattern)

通俗解释: 确保一个类只有一个实例,就像一个国家只有一个总统。

生活例子:

  • 打印机:一个办公室通常只有一台打印机,大家共用
  • 数据库连接:一个应用通常只需要一个数据库连接池

适用场景:

  • 需要全局唯一实例的场景
  • 需要控制资源访问的场景

C语言实现:

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

// 单例结构体
typedef struct {
    int value;
} Singleton;

// 静态变量,存储唯一实例
static Singleton* instance = NULL;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/**
 * 获取单例实例
 * 使用双重检查锁定(Double-Check Locking)确保线程安全
 */
Singleton* getSingleton() {
    // 第一次检查:如果实例已存在,直接返回(避免每次都加锁)
    if (instance == NULL) {
        // 加锁,确保多线程环境下只有一个线程能创建实例
        pthread_mutex_lock(&mutex);
        
        // 第二次检查:再次确认实例是否已创建
        // 因为可能另一个线程已经创建了实例
        if (instance == NULL) {
            // 创建唯一实例
            instance = (Singleton*)malloc(sizeof(Singleton));
            instance->value = 0;
            printf("创建单例实例\n");
        }
        
        // 释放锁
        pthread_mutex_unlock(&mutex);
    }
    
    return instance;
}

/**
 * 设置单例的值
 */
void setSingletonValue(int value) {
    Singleton* s = getSingleton();
    s->value = value;
}

/**
 * 获取单例的值
 */
int getSingletonValue() {
    Singleton* s = getSingleton();
    return s->value;
}

// 测试代码
int main() {
    // 获取单例实例
    Singleton* s1 = getSingleton();
    setSingletonValue(100);
    printf("s1的值: %d\n", getSingletonValue());
    
    // 再次获取,应该是同一个实例
    Singleton* s2 = getSingleton();
    printf("s2的值: %d\n", getSingletonValue());
    
    // 修改s2的值
    setSingletonValue(200);
    printf("s1的值: %d\n", getSingletonValue()); // s1的值也变了,说明是同一个实例
    
    return 0;
}

编译运行:

bash 复制代码
gcc singleton.c -o singleton -lpthread
./singleton

2. 工厂方法模式(Factory Method Pattern)

通俗解释: 定义一个创建对象的接口,让子类决定实例化哪个类。就像工厂生产产品,不同工厂生产不同产品。

生活例子:

  • 汽车工厂:有"轿车工厂"、"SUV工厂",都继承自"汽车工厂"
  • 手机工厂:有"苹果工厂"、"华为工厂",都继承自"手机工厂"

适用场景:

  • 需要创建对象,但不确定具体类型
  • 需要扩展新的产品类型

C语言实现:

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

// ========== 产品接口 ==========
// 定义产品的抽象接口
typedef struct {
    void (*use)(void* self);  // 使用产品的函数指针
    char name[50];            // 产品名称
} Product;

// 产品使用函数(虚函数)
void product_use(void* self) {
    Product* p = (Product*)self;
    printf("使用产品: %s\n", p->name);
}

// ========== 具体产品A ==========
typedef struct {
    Product base;  // 继承Product
    int typeA_data;
} ProductA;

void productA_use(void* self) {
    ProductA* pa = (ProductA*)self;
    printf("使用产品A: %s (类型A数据: %d)\n", pa->base.name, pa->typeA_data);
}

ProductA* createProductA() {
    ProductA* pa = (ProductA*)malloc(sizeof(ProductA));
    pa->base.use = productA_use;
    pa->base.name[0] = '\0';
    sprintf(pa->base.name, "产品A");
    pa->typeA_data = 100;
    return pa;
}

// ========== 具体产品B ==========
typedef struct {
    Product base;  // 继承Product
    char typeB_data[50];
} ProductB;

void productB_use(void* self) {
    ProductB* pb = (ProductB*)self;
    printf("使用产品B: %s (类型B数据: %s)\n", pb->base.name, pb->typeB_data);
}

ProductB* createProductB() {
    ProductB* pb = (ProductB*)malloc(sizeof(ProductB));
    pb->base.use = productB_use;
    pb->base.name[0] = '\0';
    sprintf(pb->base.name, "产品B");
    sprintf(pb->typeB_data, "类型B的数据");
    return pb;
}

// ========== 工厂接口 ==========
// 定义工厂的抽象接口
typedef struct {
    Product* (*createProduct)(void* self);  // 创建产品的函数指针
} Factory;

// ========== 具体工厂A ==========
typedef struct {
    Factory base;  // 继承Factory
} FactoryA;

Product* factoryA_createProduct(void* self) {
    printf("工厂A创建产品A\n");
    return (Product*)createProductA();
}

FactoryA* createFactoryA() {
    FactoryA* fa = (FactoryA*)malloc(sizeof(FactoryA));
    fa->base.createProduct = factoryA_createProduct;
    return fa;
}

// ========== 具体工厂B ==========
typedef struct {
    Factory base;  // 继承Factory
} FactoryB;

Product* factoryB_createProduct(void* self) {
    printf("工厂B创建产品B\n");
    return (Product*)createProductB();
}

FactoryB* createFactoryB() {
    FactoryB* fb = (FactoryB*)malloc(sizeof(FactoryB));
    fb->base.createProduct = factoryB_createProduct;
    return fb;
}

// ========== 测试代码 ==========
int main() {
    // 使用工厂A创建产品
    FactoryA* factoryA = createFactoryA();
    Product* product1 = factoryA->base.createProduct(factoryA);
    product1->use(product1);
    
    // 使用工厂B创建产品
    FactoryB* factoryB = createFactoryB();
    Product* product2 = factoryB->base.createProduct(factoryB);
    product2->use(product2);
    
    // 释放内存
    free(product1);
    free(product2);
    free(factoryA);
    free(factoryB);
    
    return 0;
}

编译运行:

bash 复制代码
gcc factory_method.c -o factory_method
./factory_method

3. 抽象工厂模式(Abstract Factory Pattern)

通俗解释: 提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。就像家具工厂,可以生产"现代风格"或"古典风格"的整套家具。

生活例子:

  • 家具工厂:有"现代风格工厂"(生产现代沙发、现代桌子)和"古典风格工厂"(生产古典沙发、古典桌子)
  • UI主题:有"深色主题工厂"和"浅色主题工厂",分别生产深色/浅色的按钮、窗口等

适用场景:

  • 需要创建一系列相关对象
  • 需要保证产品之间的兼容性

C语言实现:

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

// ========== 产品接口:按钮 ==========
typedef struct {
    void (*render)(void* self);
    char name[50];
} Button;

void button_render(void* self) {
    Button* b = (Button*)self;
    printf("渲染按钮: %s\n", b->name);
}

// ========== 产品接口:窗口 ==========
typedef struct {
    void (*render)(void* self);
    char name[50];
} Window;

void window_render(void* self) {
    Window* w = (Window*)self;
    printf("渲染窗口: %s\n", w->name);
}

// ========== 具体产品:现代风格按钮 ==========
typedef struct {
    Button base;
} ModernButton;

void modernButton_render(void* self) {
    ModernButton* mb = (ModernButton*)self;
    printf("渲染现代风格按钮: %s (简洁、扁平化)\n", mb->base.name);
}

ModernButton* createModernButton() {
    ModernButton* mb = (ModernButton*)malloc(sizeof(ModernButton));
    mb->base.render = modernButton_render;
    strcpy(mb->base.name, "现代按钮");
    return mb;
}

// ========== 具体产品:现代风格窗口 ==========
typedef struct {
    Window base;
} ModernWindow;

void modernWindow_render(void* self) {
    ModernWindow* mw = (ModernWindow*)self;
    printf("渲染现代风格窗口: %s (大边框、圆角)\n", mw->base.name);
}

ModernWindow* createModernWindow() {
    ModernWindow* mw = (ModernWindow*)malloc(sizeof(ModernWindow));
    mw->base.render = modernWindow_render;
    strcpy(mw->base.name, "现代窗口");
    return mw;
}

// ========== 具体产品:古典风格按钮 ==========
typedef struct {
    Button base;
} ClassicButton;

void classicButton_render(void* self) {
    ClassicButton* cb = (ClassicButton*)self;
    printf("渲染古典风格按钮: %s (华丽、装饰性强)\n", cb->base.name);
}

ClassicButton* createClassicButton() {
    ClassicButton* cb = (ClassicButton*)malloc(sizeof(ClassicButton));
    cb->base.render = classicButton_render;
    strcpy(cb->base.name, "古典按钮");
    return cb;
}

// ========== 具体产品:古典风格窗口 ==========
typedef struct {
    Window base;
} ClassicWindow;

void classicWindow_render(void* self) {
    ClassicWindow* cw = (ClassicWindow*)self;
    printf("渲染古典风格窗口: %s (小边框、雕花装饰)\n", cw->base.name);
}

ClassicWindow* createClassicWindow() {
    ClassicWindow* cw = (ClassicWindow*)malloc(sizeof(ClassicWindow));
    cw->base.render = classicWindow_render;
    strcpy(cw->base.name, "古典窗口");
    return cw;
}

// ========== 抽象工厂接口 ==========
typedef struct {
    Button* (*createButton)(void* self);
    Window* (*createWindow)(void* self);
} GUIFactory;

// ========== 具体工厂:现代风格工厂 ==========
typedef struct {
    GUIFactory base;
} ModernFactory;

Button* modernFactory_createButton(void* self) {
    printf("现代工厂创建现代按钮\n");
    return (Button*)createModernButton();
}

Window* modernFactory_createWindow(void* self) {
    printf("现代工厂创建现代窗口\n");
    return (Window*)createModernWindow();
}

ModernFactory* createModernFactory() {
    ModernFactory* mf = (ModernFactory*)malloc(sizeof(ModernFactory));
    mf->base.createButton = modernFactory_createButton;
    mf->base.createWindow = modernFactory_createWindow;
    return mf;
}

// ========== 具体工厂:古典风格工厂 ==========
typedef struct {
    GUIFactory base;
} ClassicFactory;

Button* classicFactory_createButton(void* self) {
    printf("古典工厂创建古典按钮\n");
    return (Button*)createClassicButton();
}

Window* classicFactory_createWindow(void* self) {
    printf("古典工厂创建古典窗口\n");
    return (Window*)createClassicWindow();
}

ClassicFactory* createClassicFactory() {
    ClassicFactory* cf = (ClassicFactory*)malloc(sizeof(ClassicFactory));
    cf->base.createButton = classicFactory_createButton;
    cf->base.createWindow = classicFactory_createWindow;
    return cf;
}

// ========== 客户端代码 ==========
void createUI(GUIFactory* factory) {
    printf("\n=== 创建UI界面 ===\n");
    Button* button = factory->createButton(factory);
    Window* window = factory->createWindow(factory);
    
    printf("\n=== 渲染UI ===\n");
    button->render(button);
    window->render(window);
    
    free(button);
    free(window);
}

int main() {
    // 使用现代风格工厂
    ModernFactory* modernFactory = createModernFactory();
    createUI((GUIFactory*)modernFactory);
    
    printf("\n");
    
    // 使用古典风格工厂
    ClassicFactory* classicFactory = createClassicFactory();
    createUI((GUIFactory*)classicFactory);
    
    free(modernFactory);
    free(classicFactory);
    
    return 0;
}

编译运行:

bash 复制代码
gcc abstract_factory.c -o abstract_factory
./abstract_factory

4. 建造者模式(Builder Pattern)

通俗解释: 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。就像盖房子,有设计师、施工队,一步步建造。

生活例子:

  • 盖房子:先打地基,再建框架,再装修,最后验收
  • 点餐:选择主食、配菜、饮料、甜点,最后组成套餐

适用场景:

  • 需要创建复杂对象
  • 创建过程需要多个步骤
  • 需要不同的表示形式

C语言实现:

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

// ========== 产品:房子 ==========
typedef struct {
    char foundation[50];  // 地基
    char walls[50];       // 墙壁
    char roof[50];        // 屋顶
    char interior[50];    // 内饰
} House;

void printHouse(House* house) {
    printf("=== 房子信息 ===\n");
    printf("地基: %s\n", house->foundation);
    printf("墙壁: %s\n", house->walls);
    printf("屋顶: %s\n", house->roof);
    printf("内饰: %s\n", house->interior);
    printf("================\n");
}

// ========== 建造者接口 ==========
typedef struct {
    void (*buildFoundation)(void* self, const char* type);
    void (*buildWalls)(void* self, const char* type);
    void (*buildRoof)(void* self, const char* type);
    void (*buildInterior)(void* self, const char* type);
    House* (*getHouse)(void* self);
} HouseBuilder;

// ========== 具体建造者:普通房子建造者 ==========
typedef struct {
    HouseBuilder base;
    House* house;
} NormalHouseBuilder;

void normalBuilder_buildFoundation(void* self, const char* type) {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)self;
    strcpy(builder->house->foundation, type);
    printf("建造普通房子的地基: %s\n", type);
}

void normalBuilder_buildWalls(void* self, const char* type) {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)self;
    strcpy(builder->house->walls, type);
    printf("建造普通房子的墙壁: %s\n", type);
}

void normalBuilder_buildRoof(void* self, const char* type) {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)self;
    strcpy(builder->house->roof, type);
    printf("建造普通房子的屋顶: %s\n", type);
}

void normalBuilder_buildInterior(void* self, const char* type) {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)self;
    strcpy(builder->house->interior, type);
    printf("建造普通房子的内饰: %s\n", type);
}

House* normalBuilder_getHouse(void* self) {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)self;
    return builder->house;
}

NormalHouseBuilder* createNormalHouseBuilder() {
    NormalHouseBuilder* builder = (NormalHouseBuilder*)malloc(sizeof(NormalHouseBuilder));
    builder->house = (House*)malloc(sizeof(House));
    builder->base.buildFoundation = normalBuilder_buildFoundation;
    builder->base.buildWalls = normalBuilder_buildWalls;
    builder->base.buildRoof = normalBuilder_buildRoof;
    builder->base.buildInterior = normalBuilder_buildInterior;
    builder->base.getHouse = normalBuilder_getHouse;
    return builder;
}

// ========== 具体建造者:豪华房子建造者 ==========
typedef struct {
    HouseBuilder base;
    House* house;
} LuxuryHouseBuilder;

void luxuryBuilder_buildFoundation(void* self, const char* type) {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)self;
    char luxury_type[100];
    sprintf(luxury_type, "豪华%s", type);
    strcpy(builder->house->foundation, luxury_type);
    printf("建造豪华房子的地基: %s\n", luxury_type);
}

void luxuryBuilder_buildWalls(void* self, const char* type) {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)self;
    char luxury_type[100];
    sprintf(luxury_type, "豪华%s", type);
    strcpy(builder->house->walls, luxury_type);
    printf("建造豪华房子的墙壁: %s\n", luxury_type);
}

void luxuryBuilder_buildRoof(void* self, const char* type) {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)self;
    char luxury_type[100];
    sprintf(luxury_type, "豪华%s", type);
    strcpy(builder->house->roof, luxury_type);
    printf("建造豪华房子的屋顶: %s\n", luxury_type);
}

void luxuryBuilder_buildInterior(void* self, const char* type) {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)self;
    char luxury_type[100];
    sprintf(luxury_type, "豪华%s", type);
    strcpy(builder->house->interior, luxury_type);
    printf("建造豪华房子的内饰: %s\n", luxury_type);
}

House* luxuryBuilder_getHouse(void* self) {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)self;
    return builder->house;
}

LuxuryHouseBuilder* createLuxuryHouseBuilder() {
    LuxuryHouseBuilder* builder = (LuxuryHouseBuilder*)malloc(sizeof(LuxuryHouseBuilder));
    builder->house = (House*)malloc(sizeof(House));
    builder->base.buildFoundation = luxuryBuilder_buildFoundation;
    builder->base.buildWalls = luxuryBuilder_buildWalls;
    builder->base.buildRoof = luxuryBuilder_buildRoof;
    builder->base.buildInterior = luxuryBuilder_buildInterior;
    builder->base.getHouse = luxuryBuilder_getHouse;
    return builder;
}

// ========== 导演类:负责建造流程 ==========
typedef struct {
    HouseBuilder* builder;
} Director;

void director_construct(Director* director) {
    printf("\n=== 开始建造房子 ===\n");
    // 按照固定流程建造房子
    director->builder->buildFoundation(director->builder, "混凝土");
    director->builder->buildWalls(director->builder, "砖墙");
    director->builder->buildRoof(director->builder, "瓦片");
    director->builder->buildInterior(director->builder, "简装");
    printf("=== 房子建造完成 ===\n\n");
}

Director* createDirector(HouseBuilder* builder) {
    Director* director = (Director*)malloc(sizeof(Director));
    director->builder = builder;
    return director;
}

int main() {
    // 建造普通房子
    NormalHouseBuilder* normalBuilder = createNormalHouseBuilder();
    Director* director1 = createDirector((HouseBuilder*)normalBuilder);
    director_construct(director1);
    
    House* normalHouse = normalBuilder->base.getHouse(normalBuilder);
    printHouse(normalHouse);
    
    // 建造豪华房子
    LuxuryHouseBuilder* luxuryBuilder = createLuxuryHouseBuilder();
    Director* director2 = createDirector((HouseBuilder*)luxuryBuilder);
    director_construct(director2);
    
    House* luxuryHouse = luxuryBuilder->base.getHouse(luxuryBuilder);
    printHouse(luxuryHouse);
    
    // 释放内存
    free(normalHouse);
    free(luxuryHouse);
    free(normalBuilder);
    free(luxuryBuilder);
    free(director1);
    free(director2);
    
    return 0;
}

编译运行:

bash 复制代码
gcc builder.c -o builder
./builder

5. 原型模式(Prototype Pattern)

通俗解释: 通过复制现有实例来创建新实例,而不是新建。就像复印机,可以快速复制文档。

生活例子:

  • 复印机:复制一份文档
  • 克隆:克隆羊多莉
  • 模板:用模板快速创建相似对象

适用场景:

  • 创建对象成本高(如需要大量计算或数据库查询)
  • 需要创建相似对象
  • 需要动态配置对象

C语言实现:

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

// ========== 原型接口 ==========
typedef struct {
    void* (*clone)(void* self);  // 克隆函数
    void (*display)(void* self); // 显示函数
    char name[50];
    int id;
} Prototype;

// ========== 具体原型:简历 ==========
typedef struct {
    Prototype base;
    char* workExperience;  // 工作经验
    int age;
} Resume;

// 克隆函数:深拷贝
void* resume_clone(void* self) {
    Resume* original = (Resume*)self;
    Resume* copy = (Resume*)malloc(sizeof(Resume));
    
    // 复制基本信息
    copy->base.clone = original->base.clone;
    copy->base.display = original->base.display;
    strcpy(copy->base.name, original->base.name);
    copy->base.id = original->base.id + 1000; // 新ID
    
    // 深拷贝工作经验(字符串)
    if (original->workExperience) {
        int len = strlen(original->workExperience);
        copy->workExperience = (char*)malloc(len + 1);
        strcpy(copy->workExperience, original->workExperience);
    } else {
        copy->workExperience = NULL;
    }
    
    copy->age = original->age;
    
    printf("克隆简历: %s (新ID: %d)\n", copy->base.name, copy->base.id);
    return copy;
}

// 显示函数
void resume_display(void* self) {
    Resume* r = (Resume*)self;
    printf("=== 简历信息 ===\n");
    printf("姓名: %s\n", r->base.name);
    printf("ID: %d\n", r->base.id);
    printf("年龄: %d\n", r->age);
    printf("工作经验: %s\n", r->workExperience ? r->workExperience : "无");
    printf("===============\n");
}

// 创建简历原型
Resume* createResume(const char* name, int age, const char* workExp) {
    Resume* r = (Resume*)malloc(sizeof(Resume));
    r->base.clone = resume_clone;
    r->base.display = resume_display;
    strcpy(r->base.name, name);
    r->base.id = 1001;
    r->age = age;
    
    if (workExp) {
        int len = strlen(workExp);
        r->workExperience = (char*)malloc(len + 1);
        strcpy(r->workExperience, workExp);
    } else {
        r->workExperience = NULL;
    }
    
    return r;
}

// 释放简历内存
void freeResume(Resume* r) {
    if (r) {
        if (r->workExperience) {
            free(r->workExperience);
        }
        free(r);
    }
}

// ========== 原型管理器 ==========
typedef struct {
    Prototype* prototypes[10];  // 存储原型
    int count;
} PrototypeManager;

PrototypeManager* createPrototypeManager() {
    PrototypeManager* pm = (PrototypeManager*)malloc(sizeof(PrototypeManager));
    pm->count = 0;
    return pm;
}

// 注册原型
void registerPrototype(PrototypeManager* pm, Prototype* proto) {
    if (pm->count < 10) {
        pm->prototypes[pm->count++] = proto;
        printf("注册原型: %s\n", proto->name);
    }
}

// 获取原型副本
Prototype* getPrototype(PrototypeManager* pm, int index) {
    if (index >= 0 && index < pm->count) {
        return pm->prototypes[index]->clone(pm->prototypes[index]);
    }
    return NULL;
}

int main() {
    // 创建原始简历
    Resume* originalResume = createResume("张三", 25, "5年Java开发经验");
    printf("\n=== 原始简历 ===\n");
    originalResume->base.display(originalResume);
    
    // 使用原型模式克隆简历
    printf("\n=== 克隆简历1 ===\n");
    Resume* clonedResume1 = (Resume*)originalResume->base.clone(originalResume);
    // 修改克隆后的简历
    strcpy(clonedResume1->base.name, "李四");
    clonedResume1->age = 28;
    clonedResume1->base.display(clonedResume1);
    
    printf("\n=== 克隆简历2 ===\n");
    Resume* clonedResume2 = (Resume*)originalResume->base.clone(originalResume);
    strcpy(clonedResume2->base.name, "王五");
    clonedResume2->age = 30;
    if (clonedResume2->workExperience) {
        free(clonedResume2->workExperience);
        clonedResume2->workExperience = (char*)malloc(50);
        strcpy(clonedResume2->workExperience, "3年Python开发经验");
    }
    clonedResume2->base.display(clonedResume2);
    
    // 使用原型管理器
    printf("\n=== 使用原型管理器 ===\n");
    PrototypeManager* pm = createPrototypeManager();
    registerPrototype(pm, (Prototype*)originalResume);
    
    Resume* clonedResume3 = (Resume*)getPrototype(pm, 0);
    clonedResume3->base.display(clonedResume3);
    
    // 释放内存
    freeResume(originalResume);
    freeResume(clonedResume1);
    freeResume(clonedResume2);
    freeResume(clonedResume3);
    free(pm);
    
    return 0;
}

编译运行:

bash 复制代码
gcc prototype.c -o prototype
./prototype

总结:创建型模式

创建型模式帮助我们更灵活地创建对象:

  • 单例模式:确保只有一个实例
  • 工厂方法模式:让子类决定创建什么对象
  • 抽象工厂模式:创建一系列相关对象
  • 建造者模式:分步骤创建复杂对象
  • 原型模式:通过复制创建对象

每种模式都解决了不同的对象创建问题,选择合适的模式可以让代码更清晰、更易维护。

设计模式详解:结构型模式(7个)

结构型模式关注如何组合类和对象,形成更大的结构。


1. 适配器模式(Adapter Pattern)

通俗解释: 让不兼容的接口能够一起工作。就像电源适配器,让不同国家的插头都能用。

生活例子:

  • 电源适配器:把220V电压转换成110V,让美国电器在中国能用
  • USB转HDMI:让USB接口的设备能连接HDMI显示器
  • 翻译器:让说不同语言的人能交流

适用场景:

  • 需要使用现有类,但接口不兼容
  • 需要统一多个不同接口

C语言实现:

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

// ========== 目标接口:新系统需要的接口 ==========
// 这是客户端期望的接口
typedef struct {
    void (*request)(void* self);  // 请求函数
} Target;

void target_request(void* self) {
    printf("目标接口:处理标准请求\n");
}

// ========== 被适配者:旧系统(不兼容的接口) ==========
// 这是已经存在的类,但接口不兼容
typedef struct {
    void (*specificRequest)(void* self);  // 特殊请求函数
} Adaptee;

void adaptee_specificRequest(void* self) {
    printf("被适配者:处理特殊请求(旧接口)\n");
}

Adaptee* createAdaptee() {
    Adaptee* a = (Adaptee*)malloc(sizeof(Adaptee));
    a->specificRequest = adaptee_specificRequest;
    return a;
}

// ========== 适配器:连接目标接口和被适配者 ==========
// 适配器实现了目标接口,内部使用被适配者
typedef struct {
    Target base;      // 继承目标接口
    Adaptee* adaptee; // 包含被适配者
} Adapter;

void adapter_request(void* self) {
    Adapter* adapter = (Adapter*)self;
    printf("适配器:将标准请求转换为特殊请求\n");
    // 调用被适配者的方法,实现适配
    adapter->adaptee->specificRequest(adapter->adaptee);
}

Adapter* createAdapter(Adaptee* adaptee) {
    Adapter* adapter = (Adapter*)malloc(sizeof(Adapter));
    adapter->base.request = adapter_request;
    adapter->adaptee = adaptee;
    return adapter;
}

// ========== 客户端代码 ==========
void clientCode(Target* target) {
    printf("客户端:调用目标接口\n");
    target->request(target);
}

int main() {
    printf("=== 适配器模式演示 ===\n\n");
    
    // 创建被适配者(旧系统)
    Adaptee* adaptee = createAdaptee();
    
    // 创建适配器,将旧系统适配到新接口
    Adapter* adapter = createAdapter(adaptee);
    
    // 客户端使用目标接口(新接口)
    // 适配器让旧系统看起来像新接口
    clientCode((Target*)adapter);
    
    // 释放内存
    free(adaptee);
    free(adapter);
    
    return 0;
}

编译运行:

bash 复制代码
gcc adapter.c -o adapter
./adapter

2. 桥接模式(Bridge Pattern)

通俗解释: 将抽象和实现分离,使它们可以独立变化。就像遥控器和电视,遥控器(抽象)可以控制不同品牌的电视(实现)。

生活例子:

  • 遥控器和电视:遥控器是抽象,不同品牌电视是实现
  • 画笔和颜色:画笔是抽象,不同颜色是实现
  • 操作系统和驱动程序:操作系统是抽象,不同硬件驱动是实现

适用场景:

  • 需要在运行时切换实现
  • 需要避免抽象和实现的绑定

C语言实现:

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

// ========== 实现接口:颜色(实现部分) ==========
// 这是实现部分的抽象
typedef struct {
    void (*applyColor)(void* self);  // 应用颜色
    char colorName[50];
} Color;

void color_applyColor(void* self) {
    Color* c = (Color*)self;
    printf("应用颜色: %s\n", c->colorName);
}

// ========== 具体实现:红色 ==========
typedef struct {
    Color base;
} RedColor;

void redColor_applyColor(void* self) {
    RedColor* rc = (RedColor*)self;
    printf("应用红色\n");
}

RedColor* createRedColor() {
    RedColor* rc = (RedColor*)malloc(sizeof(RedColor));
    rc->base.applyColor = redColor_applyColor;
    strcpy(rc->base.colorName, "红色");
    return rc;
}

// ========== 具体实现:蓝色 ==========
typedef struct {
    Color base;
} BlueColor;

void blueColor_applyColor(void* self) {
    BlueColor* bc = (BlueColor*)self;
    printf("应用蓝色\n");
}

BlueColor* createBlueColor() {
    BlueColor* bc = (BlueColor*)malloc(sizeof(BlueColor));
    bc->base.applyColor = blueColor_applyColor;
    strcpy(bc->base.colorName, "蓝色");
    return bc;
}

// ========== 抽象类:形状(抽象部分) ==========
// 这是抽象部分,包含对实现的引用
typedef struct {
    Color* color;  // 桥接:持有实现部分的引用
    void (*draw)(void* self);  // 绘制函数
} Shape;

void shape_draw(void* self) {
    Shape* s = (Shape*)self;
    printf("绘制形状");
    if (s->color) {
        printf(",使用");
        s->color->applyColor(s->color);
    }
}

// ========== 具体抽象:圆形 ==========
typedef struct {
    Shape base;
} Circle;

void circle_draw(void* self) {
    Circle* c = (Circle*)self;
    printf("绘制圆形");
    if (c->base.color) {
        printf(",使用");
        c->base.color->applyColor(c->base.color);
    }
    printf("\n");
}

Circle* createCircle(Color* color) {
    Circle* circle = (Circle*)malloc(sizeof(Circle));
    circle->base.color = color;  // 桥接:设置实现
    circle->base.draw = circle_draw;
    return circle;
}

// ========== 具体抽象:方形 ==========
typedef struct {
    Shape base;
} Square;

void square_draw(void* self) {
    Square* s = (Square*)self;
    printf("绘制方形");
    if (s->base.color) {
        printf(",使用");
        s->base.color->applyColor(s->base.color);
    }
    printf("\n");
}

Square* createSquare(Color* color) {
    Square* square = (Square*)malloc(sizeof(Square));
    square->base.color = color;  // 桥接:设置实现
    square->base.draw = square_draw;
    return square;
}

int main() {
    printf("=== 桥接模式演示 ===\n\n");
    
    // 创建实现:红色和蓝色
    RedColor* red = createRedColor();
    BlueColor* blue = createBlueColor();
    
    // 创建抽象:圆形和方形,并桥接到不同的颜色实现
    printf("--- 红色圆形 ---\n");
    Circle* redCircle = createCircle((Color*)red);
    redCircle->base.draw(redCircle);
    
    printf("\n--- 蓝色圆形 ---\n");
    Circle* blueCircle = createCircle((Color*)blue);
    blueCircle->base.draw(blueCircle);
    
    printf("\n--- 红色方形 ---\n");
    Square* redSquare = createSquare((Color*)red);
    redSquare->base.draw(redSquare);
    
    printf("\n--- 蓝色方形 ---\n");
    Square* blueSquare = createSquare((Color*)blue);
    blueSquare->base.draw(blueSquare);
    
    // 释放内存
    free(red);
    free(blue);
    free(redCircle);
    free(blueCircle);
    free(redSquare);
    free(blueSquare);
    
    return 0;
}

编译运行:

bash 复制代码
gcc bridge.c -o bridge
./bridge

3. 组合模式(Composite Pattern)

通俗解释: 将对象组合成树形结构,使单个对象和组合对象使用一致。就像文件夹和文件,文件夹可以包含文件,也可以包含其他文件夹。

生活例子:

  • 文件系统:文件夹可以包含文件或子文件夹
  • 组织结构:部门可以包含员工或子部门
  • 菜单系统:菜单可以包含菜单项或子菜单

适用场景:

  • 需要表示部分-整体层次结构
  • 需要统一处理单个对象和组合对象

C语言实现:

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

// ========== 组件接口 ==========
// 这是组合模式的核心接口,既可以表示叶子节点,也可以表示组合节点
typedef struct Component {
    char name[100];
    void (*operation)(struct Component* self);  // 操作函数
    void (*add)(struct Component* self, struct Component* child);      // 添加子组件
    void (*remove)(struct Component* self, struct Component* child);   // 移除子组件
    struct Component* (*getChild)(struct Component* self, int index);  // 获取子组件
} Component;

// ========== 叶子节点:文件 ==========
// 叶子节点没有子节点
typedef struct {
    Component base;
    int size;  // 文件大小
} File;

void file_operation(Component* self) {
    File* f = (File*)self;
    printf("文件: %s (大小: %d KB)\n", f->base.name, f->size);
}

void file_add(Component* self, Component* child) {
    printf("错误:文件不能添加子组件\n");
}

void file_remove(Component* self, Component* child) {
    printf("错误:文件不能移除子组件\n");
}

Component* file_getChild(Component* self, int index) {
    return NULL;  // 文件没有子节点
}

File* createFile(const char* name, int size) {
    File* f = (File*)malloc(sizeof(File));
    strcpy(f->base.name, name);
    f->size = size;
    f->base.operation = file_operation;
    f->base.add = file_add;
    f->base.remove = file_remove;
    f->base.getChild = file_getChild;
    return f;
}

// ========== 组合节点:文件夹 ==========
// 组合节点可以包含子组件
typedef struct {
    Component base;
    Component* children[100];  // 子组件数组
    int childCount;            // 子组件数量
} Folder;

void folder_operation(Component* self) {
    Folder* folder = (Folder*)self;
    printf("文件夹: %s (包含 %d 个项目)\n", folder->base.name, folder->childCount);
    
    // 递归操作所有子组件
    for (int i = 0; i < folder->childCount; i++) {
        printf("  ");
        folder->children[i]->operation(folder->children[i]);
    }
}

void folder_add(Component* self, Component* child) {
    Folder* folder = (Folder*)self;
    if (folder->childCount < 100) {
        folder->children[folder->childCount++] = child;
        printf("添加 %s 到 %s\n", child->name, folder->base.name);
    }
}

void folder_remove(Component* self, Component* child) {
    Folder* folder = (Folder*)self;
    for (int i = 0; i < folder->childCount; i++) {
        if (folder->children[i] == child) {
            // 移除子组件
            for (int j = i; j < folder->childCount - 1; j++) {
                folder->children[j] = folder->children[j + 1];
            }
            folder->childCount--;
            printf("从 %s 移除 %s\n", folder->base.name, child->name);
            return;
        }
    }
}

Component* folder_getChild(Component* self, int index) {
    Folder* folder = (Folder*)self;
    if (index >= 0 && index < folder->childCount) {
        return folder->children[index];
    }
    return NULL;
}

Folder* createFolder(const char* name) {
    Folder* folder = (Folder*)malloc(sizeof(Folder));
    strcpy(folder->base.name, name);
    folder->childCount = 0;
    folder->base.operation = folder_operation;
    folder->base.add = folder_add;
    folder->base.remove = folder_remove;
    folder->base.getChild = folder_getChild;
    return folder;
}

int main() {
    printf("=== 组合模式演示 ===\n\n");
    
    // 创建根文件夹
    Folder* root = createFolder("根目录");
    
    // 创建文件
    File* file1 = createFile("文档.txt", 10);
    File* file2 = createFile("图片.jpg", 500);
    
    // 创建子文件夹
    Folder* subFolder = createFolder("子文件夹");
    
    // 创建子文件夹中的文件
    File* file3 = createFile("数据.csv", 50);
    File* file4 = createFile("报告.pdf", 200);
    
    // 构建树形结构
    printf("--- 构建文件系统结构 ---\n");
    root->base.add((Component*)root, (Component*)file1);
    root->base.add((Component*)root, (Component*)file2);
    root->base.add((Component*)root, (Component*)subFolder);
    
    subFolder->base.add((Component*)subFolder, (Component*)file3);
    subFolder->base.add((Component*)subFolder, (Component*)file4);
    
    printf("\n--- 遍历文件系统 ---\n");
    // 统一操作:无论是文件还是文件夹,都用同样的接口
    root->base.operation((Component*)root);
    
    // 释放内存(简化版,实际应该递归释放)
    free(file1);
    free(file2);
    free(file3);
    free(file4);
    free(subFolder);
    free(root);
    
    return 0;
}

编译运行:

bash 复制代码
gcc composite.c -o composite
./composite

4. 装饰器模式(Decorator Pattern)

通俗解释: 动态地给对象添加新功能,比继承更灵活。就像给手机加保护壳、贴膜、挂件,一层层装饰。

生活例子:

  • 手机装饰:手机 + 保护壳 + 贴膜 + 挂件
  • 咖啡:咖啡 + 糖 + 牛奶 + 奶油
  • 披萨:基础披萨 + 芝士 + 香肠 + 蔬菜

适用场景:

  • 需要动态添加功能
  • 不想使用继承扩展功能

C语言实现:

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

// ========== 组件接口:咖啡 ==========
typedef struct {
    char description[100];
    int (*cost)(void* self);  // 计算价格
    void (*getDescription)(void* self, char* buffer);  // 获取描述
} Coffee;

int coffee_cost(void* self) {
    return 0;
}

void coffee_getDescription(void* self, char* buffer) {
    Coffee* c = (Coffee*)self;
    strcpy(buffer, c->description);
}

// ========== 具体组件:基础咖啡 ==========
typedef struct {
    Coffee base;
} SimpleCoffee;

int simpleCoffee_cost(void* self) {
    return 10;  // 基础咖啡10元
}

void simpleCoffee_getDescription(void* self, char* buffer) {
    strcpy(buffer, "基础咖啡");
}

SimpleCoffee* createSimpleCoffee() {
    SimpleCoffee* sc = (SimpleCoffee*)malloc(sizeof(SimpleCoffee));
    strcpy(sc->base.description, "基础咖啡");
    sc->base.cost = simpleCoffee_cost;
    sc->base.getDescription = simpleCoffee_getDescription;
    return sc;
}

// ========== 装饰器基类 ==========
typedef struct {
    Coffee base;
    Coffee* coffee;  // 被装饰的咖啡
} CoffeeDecorator;

// ========== 具体装饰器:加糖 ==========
typedef struct {
    CoffeeDecorator base;
} SugarDecorator;

int sugarDecorator_cost(void* self) {
    SugarDecorator* sd = (SugarDecorator*)self;
    return sd->base.coffee->cost(sd->base.coffee) + 2;  // 加2元
}

void sugarDecorator_getDescription(void* self, char* buffer) {
    SugarDecorator* sd = (SugarDecorator*)self;
    char temp[200];
    sd->base.coffee->getDescription(sd->base.coffee, temp);
    sprintf(buffer, "%s + 糖", temp);
}

SugarDecorator* createSugarDecorator(Coffee* coffee) {
    SugarDecorator* sd = (SugarDecorator*)malloc(sizeof(SugarDecorator));
    sd->base.coffee = coffee;
    sd->base.cost = sugarDecorator_cost;
    sd->base.getDescription = sugarDecorator_getDescription;
    return sd;
}

// ========== 具体装饰器:加牛奶 ==========
typedef struct {
    CoffeeDecorator base;
} MilkDecorator;

int milkDecorator_cost(void* self) {
    MilkDecorator* md = (MilkDecorator*)self;
    return md->base.coffee->cost(md->base.coffee) + 3;  // 加3元
}

void milkDecorator_getDescription(void* self, char* buffer) {
    MilkDecorator* md = (MilkDecorator*)self;
    char temp[200];
    md->base.coffee->getDescription(md->base.coffee, temp);
    sprintf(buffer, "%s + 牛奶", temp);
}

MilkDecorator* createMilkDecorator(Coffee* coffee) {
    MilkDecorator* md = (MilkDecorator*)malloc(sizeof(MilkDecorator));
    md->base.coffee = coffee;
    md->base.cost = milkDecorator_cost;
    md->base.getDescription = milkDecorator_getDescription;
    return md;
}

// ========== 具体装饰器:加奶油 ==========
typedef struct {
    CoffeeDecorator base;
} CreamDecorator;

int creamDecorator_cost(void* self) {
    CreamDecorator* cd = (CreamDecorator*)self;
    return cd->base.coffee->cost(cd->base.coffee) + 4;  // 加4元
}

void creamDecorator_getDescription(void* self, char* buffer) {
    CreamDecorator* cd = (CreamDecorator*)self;
    char temp[200];
    cd->base.coffee->getDescription(cd->base.coffee, temp);
    sprintf(buffer, "%s + 奶油", temp);
}

CreamDecorator* createCreamDecorator(Coffee* coffee) {
    CreamDecorator* cd = (CreamDecorator*)malloc(sizeof(CreamDecorator));
    cd->base.coffee = coffee;
    cd->base.cost = creamDecorator_cost;
    cd->base.getDescription = creamDecorator_getDescription;
    return cd;
}

int main() {
    printf("=== 装饰器模式演示 ===\n\n");
    
    // 创建基础咖啡
    SimpleCoffee* coffee = createSimpleCoffee();
    char desc[200];
    coffee->base.getDescription(&coffee->base, desc);
    printf("订单1: %s\n", desc);
    printf("价格: %d元\n\n", coffee->base.cost(&coffee->base));
    
    // 装饰:加糖
    SugarDecorator* coffeeWithSugar = createSugarDecorator((Coffee*)coffee);
    coffeeWithSugar->base.getDescription((Coffee*)coffeeWithSugar, desc);
    printf("订单2: %s\n", desc);
    printf("价格: %d元\n\n", coffeeWithSugar->base.cost((Coffee*)coffeeWithSugar));
    
    // 装饰:加糖 + 牛奶
    MilkDecorator* coffeeWithSugarMilk = createMilkDecorator((Coffee*)coffeeWithSugar);
    coffeeWithSugarMilk->base.getDescription((Coffee*)coffeeWithSugarMilk, desc);
    printf("订单3: %s\n", desc);
    printf("价格: %d元\n\n", coffeeWithSugarMilk->base.cost((Coffee*)coffeeWithSugarMilk));
    
    // 装饰:加糖 + 牛奶 + 奶油
    CreamDecorator* coffeeWithAll = createCreamDecorator((Coffee*)coffeeWithSugarMilk);
    coffeeWithAll->base.getDescription((Coffee*)coffeeWithAll, desc);
    printf("订单4: %s\n", desc);
    printf("价格: %d元\n\n", coffeeWithAll->base.cost((Coffee*)coffeeWithAll));
    
    // 释放内存(简化版)
    free(coffee);
    free(coffeeWithSugar);
    free(coffeeWithSugarMilk);
    free(coffeeWithAll);
    
    return 0;
}

编译运行:

bash 复制代码
gcc decorator.c -o decorator
./decorator

5. 外观模式(Facade Pattern)

通俗解释: 为复杂子系统提供一个简单接口。就像一键启动电脑,不需要知道CPU、内存、硬盘如何协调工作。

生活例子:

  • 一键启动:一键启动电脑,隐藏了复杂的启动过程
  • 银行ATM:简单的界面,背后是复杂的银行系统
  • 智能家居:一个APP控制所有设备,隐藏了复杂的通信协议

适用场景:

  • 需要简化复杂子系统
  • 需要解耦客户端和子系统

C语言实现:

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

// ========== 子系统1:CPU ==========
typedef struct {
    void (*start)(void);
    void (*stop)(void);
} CPU;

void cpu_start(void) {
    printf("CPU: 启动\n");
}

void cpu_stop(void) {
    printf("CPU: 停止\n");
}

CPU* createCPU() {
    CPU* cpu = (CPU*)malloc(sizeof(CPU));
    cpu->start = cpu_start;
    cpu->stop = cpu_stop;
    return cpu;
}

// ========== 子系统2:内存 ==========
typedef struct {
    void (*load)(void);
    void (*unload)(void);
} Memory;

void memory_load(void) {
    printf("内存: 加载数据\n");
}

void memory_unload(void) {
    printf("内存: 卸载数据\n");
}

Memory* createMemory() {
    Memory* mem = (Memory*)malloc(sizeof(Memory));
    mem->load = memory_load;
    mem->unload = memory_unload;
    return mem;
}

// ========== 子系统3:硬盘 ==========
typedef struct {
    void (*read)(void);
    void (*write)(void);
} HardDrive;

void hardDrive_read(void) {
    printf("硬盘: 读取数据\n");
}

void hardDrive_write(void) {
    printf("硬盘: 写入数据\n");
}

HardDrive* createHardDrive() {
    HardDrive* hd = (HardDrive*)malloc(sizeof(HardDrive));
    hd->read = hardDrive_read;
    hd->write = hardDrive_write;
    return hd;
}

// ========== 外观类:计算机 ==========
// 外观类封装了子系统的复杂操作,提供简单接口
typedef struct {
    CPU* cpu;
    Memory* memory;
    HardDrive* hardDrive;
    void (*startComputer)(void* self);
    void (*stopComputer)(void* self);
} Computer;

void computer_startComputer(void* self) {
    Computer* comp = (Computer*)self;
    printf("=== 启动计算机 ===\n");
    comp->cpu->start();
    comp->memory->load();
    comp->hardDrive->read();
    printf("计算机启动完成!\n\n");
}

void computer_stopComputer(void* self) {
    Computer* comp = (Computer*)self;
    printf("=== 关闭计算机 ===\n");
    comp->hardDrive->write();
    comp->memory->unload();
    comp->cpu->stop();
    printf("计算机关闭完成!\n\n");
}

Computer* createComputer() {
    Computer* comp = (Computer*)malloc(sizeof(Computer));
    comp->cpu = createCPU();
    comp->memory = createMemory();
    comp->hardDrive = createHardDrive();
    comp->startComputer = computer_startComputer;
    comp->stopComputer = computer_stopComputer;
    return comp;
}

void freeComputer(Computer* comp) {
    if (comp) {
        free(comp->cpu);
        free(comp->memory);
        free(comp->hardDrive);
        free(comp);
    }
}

int main() {
    printf("=== 外观模式演示 ===\n\n");
    
    // 创建计算机(外观对象)
    Computer* computer = createComputer();
    
    // 客户端只需要调用简单接口,不需要知道子系统细节
    printf("--- 用户操作:启动电脑 ---\n");
    computer->startComputer(computer);
    
    printf("--- 用户操作:关闭电脑 ---\n");
    computer->stopComputer(computer);
    
    // 如果不使用外观模式,客户端需要这样操作(复杂):
    printf("--- 不使用外观模式(复杂) ---\n");
    CPU* cpu = createCPU();
    Memory* mem = createMemory();
    HardDrive* hd = createHardDrive();
    
    cpu->start();
    mem->load();
    hd->read();
    
    hd->write();
    mem->unload();
    cpu->stop();
    
    // 释放内存
    freeComputer(computer);
    free(cpu);
    free(mem);
    free(hd);
    
    return 0;
}

编译运行:

bash 复制代码
gcc facade.c -o facade
./facade

6. 享元模式(Flyweight Pattern)

通俗解释: 通过共享相同数据来减少内存使用。就像图书馆,多个人可以共享同一本书,而不需要每人买一本。

生活例子:

  • 图书馆:多个人共享同一本书
  • 字体:多个字符共享同一字体对象
  • 游戏:多个敌人共享同一模型和纹理

适用场景:

  • 需要创建大量相似对象
  • 对象的大部分状态可以共享

C语言实现:

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

// ========== 享元接口:字符 ==========
typedef struct {
    char symbol;      // 字符(内部状态,可共享)
    void (*display)(void* self, int x, int y);  // 显示函数
} Character;

// ========== 具体享元:具体字符 ==========
typedef struct {
    Character base;
    char font[50];    // 字体(内部状态,可共享)
    int size;         // 大小(内部状态,可共享)
} ConcreteCharacter;

void character_display(void* self, int x, int y) {
    ConcreteCharacter* cc = (ConcreteCharacter*)self;
    printf("显示字符 '%c' (字体: %s, 大小: %d) 在位置 (%d, %d)\n", 
           cc->base.symbol, cc->font, cc->size, x, y);
}

ConcreteCharacter* createCharacter(char symbol, const char* font, int size) {
    ConcreteCharacter* cc = (ConcreteCharacter*)malloc(sizeof(ConcreteCharacter));
    cc->base.symbol = symbol;
    strcpy(cc->font, font);
    cc->size = size;
    cc->base.display = character_display;
    return cc;
}

// ========== 享元工厂:管理享元对象 ==========
typedef struct {
    ConcreteCharacter* characters[100];  // 享元对象池
    int count;
} CharacterFactory;

CharacterFactory* createCharacterFactory() {
    CharacterFactory* factory = (CharacterFactory*)malloc(sizeof(CharacterFactory));
    factory->count = 0;
    return factory;
}

// 获取享元对象(如果不存在则创建)
ConcreteCharacter* getCharacter(CharacterFactory* factory, char symbol, const char* font, int size) {
    // 查找是否已存在相同的享元对象
    for (int i = 0; i < factory->count; i++) {
        ConcreteCharacter* cc = factory->characters[i];
        if (cc->base.symbol == symbol && 
            strcmp(cc->font, font) == 0 && 
            cc->size == size) {
            printf("复用享元对象: '%c'\n", symbol);
            return cc;  // 返回已存在的对象
        }
    }
    
    // 不存在,创建新的享元对象
    printf("创建新享元对象: '%c'\n", symbol);
    ConcreteCharacter* cc = createCharacter(symbol, font, size);
    factory->characters[factory->count++] = cc;
    return cc;
}

// ========== 外部状态:位置信息 ==========
// 这些是外部状态,不存储在享元对象中
typedef struct {
    Character* character;  // 享元对象引用
    int x;                // 外部状态:X坐标
    int y;                // 外部状态:Y坐标
} CharacterContext;

CharacterContext* createCharacterContext(Character* ch, int x, int y) {
    CharacterContext* ctx = (CharacterContext*)malloc(sizeof(CharacterContext));
    ctx->character = ch;
    ctx->x = x;
    ctx->y = y;
    return ctx;
}

void displayContext(CharacterContext* ctx) {
    ctx->character->display(ctx->character, ctx->x, ctx->y);
}

int main() {
    printf("=== 享元模式演示 ===\n\n");
    
    // 创建享元工厂
    CharacterFactory* factory = createCharacterFactory();
    
    // 创建字符上下文(包含外部状态)
    printf("--- 创建文本 ---\n");
    CharacterContext* contexts[10];
    int contextCount = 0;
    
    // 创建多个字符,但相同字符会共享享元对象
    contexts[contextCount++] = createCharacterContext(
        (Character*)getCharacter(factory, 'H', "Arial", 12), 0, 0);
    contexts[contextCount++] = createCharacterContext(
        (Character*)getCharacter(factory, 'e', "Arial", 12), 10, 0);
    contexts[contextCount++] = createCharacterContext(
        (Character*)getCharacter(factory, 'l', "Arial", 12), 20, 0);
    contexts[contextCount++] = createCharacterContext(
        (Character*)getCharacter(factory, 'l', "Arial", 12), 30, 0);  // 复用'l'
    contexts[contextCount++] = createCharacterContext(
        (Character*)getCharacter(factory, 'o', "Arial", 12), 40, 0);
    
    printf("\n--- 显示文本 ---\n");
    for (int i = 0; i < contextCount; i++) {
        displayContext(contexts[i]);
    }
    
    printf("\n--- 统计信息 ---\n");
    printf("文本长度: %d 个字符\n", contextCount);
    printf("实际创建的享元对象: %d 个\n", factory->count);
    printf("节省内存: %d 个对象\n", contextCount - factory->count);
    
    // 释放内存(简化版)
    for (int i = 0; i < contextCount; i++) {
        free(contexts[i]);
    }
    for (int i = 0; i < factory->count; i++) {
        free(factory->characters[i]);
    }
    free(factory);
    
    return 0;
}

编译运行:

bash 复制代码
gcc flyweight.c -o flyweight
./flyweight

7. 代理模式(Proxy Pattern)

通俗解释: 为其他对象提供代理以控制对这个对象的访问。就像代购,你通过代购买东西,代购控制你和商家的交互。

生活例子:

  • 代购:代购代理你购买商品
  • 门禁卡:门禁卡代理你开门
  • 缓存代理:缓存代理数据库,减少数据库访问

适用场景:

  • 需要控制对象访问
  • 需要延迟加载
  • 需要添加额外功能(如缓存、日志)

C语言实现:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>  // 用于sleep函数

// ========== 主题接口:图像 ==========
typedef struct {
    void (*display)(void* self);  // 显示函数
    char filename[100];
} Image;

void image_display(void* self) {
    Image* img = (Image*)self;
    printf("显示图像: %s\n", img->filename);
}

// ========== 真实主题:真实图像 ==========
// 这是实际的对象,可能创建成本很高
typedef struct {
    Image base;
} RealImage;

void realImage_display(void* self) {
    RealImage* ri = (RealImage*)self;
    printf("从磁盘加载图像: %s\n", ri->base.filename);
    sleep(1);  // 模拟加载时间
    printf("显示真实图像: %s\n", ri->base.filename);
}

RealImage* createRealImage(const char* filename) {
    RealImage* ri = (RealImage*)malloc(sizeof(RealImage));
    strcpy(ri->base.filename, filename);
    ri->base.display = realImage_display;
    printf("创建真实图像对象: %s\n", filename);
    return ri;
}

// ========== 代理:图像代理 ==========
// 代理控制对真实图像的访问
typedef struct {
    Image base;
    RealImage* realImage;  // 真实图像的引用
    int loaded;            // 是否已加载
} ProxyImage;

void proxyImage_display(void* self) {
    ProxyImage* proxy = (ProxyImage*)self;
    
    // 延迟加载:只有在需要时才创建真实对象
    if (!proxy->loaded) {
        printf("代理:延迟加载图像\n");
        proxy->realImage = createRealImage(proxy->base.filename);
        proxy->loaded = 1;
    }
    
    // 调用真实对象的显示方法
    proxy->realImage->base.display(&proxy->realImage->base);
}

ProxyImage* createProxyImage(const char* filename) {
    ProxyImage* proxy = (ProxyImage*)malloc(sizeof(ProxyImage));
    strcpy(proxy->base.filename, filename);
    proxy->base.display = proxyImage_display;
    proxy->realImage = NULL;
    proxy->loaded = 0;
    printf("创建图像代理: %s\n", filename);
    return proxy;
}

int main() {
    printf("=== 代理模式演示 ===\n\n");
    
    // 创建代理对象(此时真实对象还未创建)
    ProxyImage* proxy1 = createProxyImage("photo1.jpg");
    ProxyImage* proxy2 = createProxyImage("photo2.jpg");
    
    printf("\n--- 第一次显示图像1 ---\n");
    // 第一次调用:代理会创建真实对象
    proxy1->base.display(proxy1);
    
    printf("\n--- 第一次显示图像2 ---\n");
    proxy2->base.display(proxy2);
    
    printf("\n--- 第二次显示图像1(已缓存) ---\n");
    // 第二次调用:直接使用已创建的真实对象
    proxy1->base.display(proxy1);
    
    // 释放内存
    if (proxy1->realImage) {
        free(proxy1->realImage);
    }
    if (proxy2->realImage) {
        free(proxy2->realImage);
    }
    free(proxy1);
    free(proxy2);
    
    return 0;
}

编译运行:

bash 复制代码
gcc proxy.c -o proxy
./proxy

总结:结构型模式

结构型模式帮助我们组合类和对象,形成更大的结构:

  • 适配器模式:让不兼容的接口能够一起工作
  • 桥接模式:将抽象和实现分离
  • 组合模式:统一处理单个对象和组合对象
  • 装饰器模式:动态添加功能
  • 外观模式:简化复杂子系统
  • 享元模式:共享数据减少内存
  • 代理模式:控制对象访问

每种模式都解决了不同的结构问题,让代码更灵活、更易维护。

设计模式详解:行为型模式(11个)

行为型模式关注对象之间的通信和职责分配。


1. 责任链模式(Chain of Responsibility Pattern)

通俗解释: 将请求沿着处理者链传递,直到有处理者处理它。就像请假,先找组长,组长处理不了找经理,经理处理不了找总经理。

生活例子:

  • 请假流程:员工 → 组长 → 经理 → 总经理
  • 客服系统:一级客服 → 二级客服 → 三级客服
  • 异常处理:try-catch链式处理

适用场景:

  • 有多个对象可以处理请求
  • 不确定哪个对象处理请求
  • 需要动态指定处理者

C语言实现:

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

// ========== 请求类型 ==========
typedef struct {
    int amount;      // 金额
    char type[50];   // 类型
} Request;

Request* createRequest(int amount, const char* type) {
    Request* req = (Request*)malloc(sizeof(Request));
    req->amount = amount;
    strcpy(req->type, type);
    return req;
}

// ========== 处理者接口 ==========
typedef struct Handler {
    struct Handler* next;  // 下一个处理者
    int limit;            // 处理权限上限
    char name[50];        // 处理者名称
    int (*handle)(struct Handler* self, Request* request);  // 处理函数
    void (*setNext)(struct Handler* self, struct Handler* next);  // 设置下一个处理者
} Handler;

// 设置下一个处理者
void handler_setNext(Handler* self, Handler* next) {
    self->next = next;
}

// 处理请求(模板方法)
int handler_handle(Handler* self, Request* request) {
    // 如果当前处理者可以处理
    if (request->amount <= self->limit) {
        printf("%s 处理了请求: %s, 金额: %d\n", self->name, request->type, request->amount);
        return 1;  // 处理成功
    }
    
    // 如果不能处理,传递给下一个处理者
    if (self->next != NULL) {
        printf("%s 无法处理,传递给下一个处理者\n", self->name);
        return self->next->handle(self->next, request);
    }
    
    // 没有处理者能处理
    printf("没有处理者能处理该请求\n");
    return 0;
}

// ========== 具体处理者:组长 ==========
typedef struct {
    Handler base;
} GroupLeader;

int groupLeader_handle(Handler* self, Request* request) {
    self->limit = 1000;  // 组长最多处理1000元
    strcpy(self->name, "组长");
    return handler_handle(self, request);
}

GroupLeader* createGroupLeader() {
    GroupLeader* gl = (GroupLeader*)malloc(sizeof(GroupLeader));
    gl->base.handle = groupLeader_handle;
    gl->base.setNext = handler_setNext;
    gl->base.next = NULL;
    return gl;
}

// ========== 具体处理者:经理 ==========
typedef struct {
    Handler base;
} Manager;

int manager_handle(Handler* self, Request* request) {
    self->limit = 5000;  // 经理最多处理5000元
    strcpy(self->name, "经理");
    return handler_handle(self, request);
}

Manager* createManager() {
    Manager* m = (Manager*)malloc(sizeof(Manager));
    m->base.handle = manager_handle;
    m->base.setNext = handler_setNext;
    m->base.next = NULL;
    return m;
}

// ========== 具体处理者:总经理 ==========
typedef struct {
    Handler base;
} GeneralManager;

int generalManager_handle(Handler* self, Request* request) {
    self->limit = 50000;  // 总经理最多处理50000元
    strcpy(self->name, "总经理");
    return handler_handle(self, request);
}

GeneralManager* createGeneralManager() {
    GeneralManager* gm = (GeneralManager*)malloc(sizeof(GeneralManager));
    gm->base.handle = generalManager_handle;
    gm->base.setNext = handler_setNext;
    gm->base.next = NULL;
    return gm;
}

int main() {
    printf("=== 责任链模式演示 ===\n\n");
    
    // 创建处理者链
    GroupLeader* leader = createGroupLeader();
    Manager* manager = createManager();
    GeneralManager* gm = createGeneralManager();
    
    // 设置责任链:组长 -> 经理 -> 总经理
    leader->base.setNext(&leader->base, (Handler*)manager);
    manager->base.setNext((Handler*)manager, (Handler*)gm);
    
    // 创建不同的请求
    printf("--- 请求1: 500元 ---\n");
    Request* req1 = createRequest(500, "差旅费");
    leader->base.handle((Handler*)leader, req1);
    
    printf("\n--- 请求2: 3000元 ---\n");
    Request* req2 = createRequest(3000, "设备采购");
    leader->base.handle((Handler*)leader, req2);
    
    printf("\n--- 请求3: 20000元 ---\n");
    Request* req3 = createRequest(20000, "项目投资");
    leader->base.handle((Handler*)leader, req3);
    
    printf("\n--- 请求4: 100000元(超出所有处理者权限) ---\n");
    Request* req4 = createRequest(100000, "大额投资");
    leader->base.handle((Handler*)leader, req4);
    
    // 释放内存
    free(req1);
    free(req2);
    free(req3);
    free(req4);
    free(leader);
    free(manager);
    free(gm);
    
    return 0;
}

编译运行:

bash 复制代码
gcc chain_of_responsibility.c -o chain_of_responsibility
./chain_of_responsibility

2. 命令模式(Command Pattern)

通俗解释: 将请求封装成对象,从而可以用不同的请求对客户进行参数化。就像遥控器,每个按钮都是一个命令对象。

生活例子:

  • 遥控器:每个按钮是一个命令,可以控制电视
  • 菜单:每个菜单项是一个命令
  • 撤销/重做:命令可以保存,支持撤销和重做

适用场景:

  • 需要将请求参数化
  • 需要支持撤销/重做
  • 需要记录请求日志

C语言实现:

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

// ========== 接收者:电视 ==========
// 这是实际执行操作的对象
typedef struct {
    int volume;      // 音量
    int channel;     // 频道
    int isOn;        // 是否开机
} TV;

TV* createTV() {
    TV* tv = (TV*)malloc(sizeof(TV));
    tv->volume = 50;
    tv->channel = 1;
    tv->isOn = 0;
    return tv;
}

void tv_turnOn(TV* tv) {
    tv->isOn = 1;
    printf("电视已开机\n");
}

void tv_turnOff(TV* tv) {
    tv->isOn = 0;
    printf("电视已关机\n");
}

void tv_setVolume(TV* tv, int volume) {
    tv->volume = volume;
    printf("设置音量为: %d\n", volume);
}

void tv_setChannel(TV* tv, int channel) {
    tv->channel = channel;
    printf("设置频道为: %d\n", channel);
}

void tv_showStatus(TV* tv) {
    printf("=== 电视状态 ===\n");
    printf("状态: %s\n", tv->isOn ? "开机" : "关机");
    printf("音量: %d\n", tv->volume);
    printf("频道: %d\n", tv->channel);
    printf("==============\n");
}

// ========== 命令接口 ==========
typedef struct {
    void (*execute)(void* self);      // 执行命令
    void (*undo)(void* self);         // 撤销命令
    char description[100];            // 命令描述
} Command;

// ========== 具体命令:开机命令 ==========
typedef struct {
    Command base;
    TV* tv;
    int previousState;  // 保存之前的状态,用于撤销
} TurnOnCommand;

void turnOnCommand_execute(void* self) {
    TurnOnCommand* cmd = (TurnOnCommand*)self;
    cmd->previousState = cmd->tv->isOn;
    tv_turnOn(cmd->tv);
}

void turnOnCommand_undo(void* self) {
    TurnOnCommand* cmd = (TurnOnCommand*)self;
    if (!cmd->previousState) {
        tv_turnOff(cmd->tv);
    }
}

TurnOnCommand* createTurnOnCommand(TV* tv) {
    TurnOnCommand* cmd = (TurnOnCommand*)malloc(sizeof(TurnOnCommand));
    cmd->base.execute = turnOnCommand_execute;
    cmd->base.undo = turnOnCommand_undo;
    strcpy(cmd->base.description, "开机");
    cmd->tv = tv;
    return cmd;
}

// ========== 具体命令:关机命令 ==========
typedef struct {
    Command base;
    TV* tv;
    int previousState;
} TurnOffCommand;

void turnOffCommand_execute(void* self) {
    TurnOffCommand* cmd = (TurnOffCommand*)self;
    cmd->previousState = cmd->tv->isOn;
    tv_turnOff(cmd->tv);
}

void turnOffCommand_undo(void* self) {
    TurnOffCommand* cmd = (TurnOffCommand*)self;
    if (cmd->previousState) {
        tv_turnOn(cmd->tv);
    }
}

TurnOffCommand* createTurnOffCommand(TV* tv) {
    TurnOffCommand* cmd = (TurnOffCommand*)malloc(sizeof(TurnOffCommand));
    cmd->base.execute = turnOffCommand_execute;
    cmd->base.undo = turnOffCommand_undo;
    strcpy(cmd->base.description, "关机");
    cmd->tv = tv;
    return cmd;
}

// ========== 具体命令:设置音量命令 ==========
typedef struct {
    Command base;
    TV* tv;
    int volume;
    int previousVolume;
} SetVolumeCommand;

void setVolumeCommand_execute(void* self) {
    SetVolumeCommand* cmd = (SetVolumeCommand*)self;
    cmd->previousVolume = cmd->tv->volume;
    tv_setVolume(cmd->tv, cmd->volume);
}

void setVolumeCommand_undo(void* self) {
    SetVolumeCommand* cmd = (SetVolumeCommand*)self;
    tv_setVolume(cmd->tv, cmd->previousVolume);
}

SetVolumeCommand* createSetVolumeCommand(TV* tv, int volume) {
    SetVolumeCommand* cmd = (SetVolumeCommand*)malloc(sizeof(SetVolumeCommand));
    cmd->base.execute = setVolumeCommand_execute;
    cmd->base.undo = setVolumeCommand_undo;
    sprintf(cmd->base.description, "设置音量为%d", volume);
    cmd->tv = tv;
    cmd->volume = volume;
    return cmd;
}

// ========== 调用者:遥控器 ==========
// 这是发送命令的对象
typedef struct {
    Command* command;  // 当前命令
    Command* history[100];  // 命令历史(用于撤销)
    int historyCount;
} RemoteControl;

RemoteControl* createRemoteControl() {
    RemoteControl* rc = (RemoteControl*)malloc(sizeof(RemoteControl));
    rc->command = NULL;
    rc->historyCount = 0;
    return rc;
}

void remoteControl_setCommand(RemoteControl* rc, Command* cmd) {
    rc->command = cmd;
}

void remoteControl_pressButton(RemoteControl* rc) {
    if (rc->command != NULL) {
        printf("执行命令: %s\n", rc->command->description);
        rc->command->execute(rc->command);
        // 保存到历史
        if (rc->historyCount < 100) {
            rc->history[rc->historyCount++] = rc->command;
        }
    }
}

void remoteControl_undo(RemoteControl* rc) {
    if (rc->historyCount > 0) {
        Command* lastCmd = rc->history[--rc->historyCount];
        printf("撤销命令: %s\n", lastCmd->description);
        lastCmd->undo(lastCmd);
    } else {
        printf("没有可撤销的命令\n");
    }
}

int main() {
    printf("=== 命令模式演示 ===\n\n");
    
    // 创建接收者(电视)
    TV* tv = createTV();
    tv_showStatus(tv);
    
    // 创建命令
    TurnOnCommand* turnOn = createTurnOnCommand(tv);
    SetVolumeCommand* setVol = createSetVolumeCommand(tv, 80);
    TurnOffCommand* turnOff = createTurnOffCommand(tv);
    
    // 创建调用者(遥控器)
    RemoteControl* remote = createRemoteControl();
    
    // 执行命令
    printf("\n--- 执行命令 ---\n");
    remoteControl_setCommand(remote, (Command*)turnOn);
    remoteControl_pressButton(remote);
    
    remoteControl_setCommand(remote, (Command*)setVol);
    remoteControl_pressButton(remote);
    
    tv_showStatus(tv);
    
    // 撤销命令
    printf("\n--- 撤销命令 ---\n");
    remoteControl_undo(remote);
    tv_showStatus(tv);
    
    remoteControl_undo(remote);
    tv_showStatus(tv);
    
    // 释放内存
    free(tv);
    free(turnOn);
    free(setVol);
    free(turnOff);
    free(remote);
    
    return 0;
}

编译运行:

bash 复制代码
gcc command.c -o command
./command

3. 解释器模式(Interpreter Pattern)

通俗解释: 定义语言的文法,并解释该语言中的句子。就像编译器,解释代码的含义。

生活例子:

  • 计算器:解释数学表达式
  • 正则表达式:解释匹配规则
  • SQL解释器:解释SQL语句

适用场景:

  • 需要解释特定语言
  • 语法简单,性能要求不高

C语言实现:

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

// ========== 表达式接口 ==========
typedef struct {
    int (*interpret)(void* self);  // 解释函数
} Expression;

// ========== 终结符表达式:数字 ==========
typedef struct {
    Expression base;
    int value;
} NumberExpression;

int numberExpression_interpret(void* self) {
    NumberExpression* ne = (NumberExpression*)self;
    return ne->value;
}

NumberExpression* createNumberExpression(int value) {
    NumberExpression* ne = (NumberExpression*)malloc(sizeof(NumberExpression));
    ne->base.interpret = numberExpression_interpret;
    ne->value = value;
    return ne;
}

// ========== 非终结符表达式:加法 ==========
typedef struct {
    Expression base;
    Expression* left;   // 左表达式
    Expression* right;  // 右表达式
} AddExpression;

int addExpression_interpret(void* self) {
    AddExpression* ae = (AddExpression*)self;
    int leftValue = ae->left->interpret(ae->left);
    int rightValue = ae->right->interpret(ae->right);
    return leftValue + rightValue;
}

AddExpression* createAddExpression(Expression* left, Expression* right) {
    AddExpression* ae = (AddExpression*)malloc(sizeof(AddExpression));
    ae->base.interpret = addExpression_interpret;
    ae->left = left;
    ae->right = right;
    return ae;
}

// ========== 非终结符表达式:减法 ==========
typedef struct {
    Expression base;
    Expression* left;
    Expression* right;
} SubtractExpression;

int subtractExpression_interpret(void* self) {
    SubtractExpression* se = (SubtractExpression*)self;
    int leftValue = se->left->interpret(se->left);
    int rightValue = se->right->interpret(se->right);
    return leftValue - rightValue;
}

SubtractExpression* createSubtractExpression(Expression* left, Expression* right) {
    SubtractExpression* se = (SubtractExpression*)malloc(sizeof(SubtractExpression));
    se->base.interpret = subtractExpression_interpret;
    se->left = left;
    se->right = right;
    return se;
}

// ========== 非终结符表达式:乘法 ==========
typedef struct {
    Expression base;
    Expression* left;
    Expression* right;
} MultiplyExpression;

int multiplyExpression_interpret(void* self) {
    MultiplyExpression* me = (MultiplyExpression*)self;
    int leftValue = me->left->interpret(me->left);
    int rightValue = me->right->interpret(me->right);
    return leftValue * rightValue;
}

MultiplyExpression* createMultiplyExpression(Expression* left, Expression* right) {
    MultiplyExpression* me = (MultiplyExpression*)malloc(sizeof(MultiplyExpression));
    me->base.interpret = multiplyExpression_interpret;
    me->left = left;
    me->right = right;
    return me;
}

// ========== 上下文:解析器 ==========
// 简化版解析器,解析 "数字 运算符 数字" 格式
Expression* parseExpression(const char* expr) {
    // 这里简化处理,实际应该用更复杂的解析器
    // 示例:解析 "5 + 3" 或 "10 - 2" 或 "4 * 2"
    int num1 = 0, num2 = 0;
    char op = '+';
    
    // 简单解析(实际应该用词法分析器和语法分析器)
    sscanf(expr, "%d %c %d", &num1, &op, &num2);
    
    Expression* left = (Expression*)createNumberExpression(num1);
    Expression* right = (Expression*)createNumberExpression(num2);
    
    switch (op) {
        case '+':
            return (Expression*)createAddExpression(left, right);
        case '-':
            return (Expression*)createSubtractExpression(left, right);
        case '*':
            return (Expression*)createMultiplyExpression(left, right);
        default:
            return left;
    }
}

int main() {
    printf("=== 解释器模式演示 ===\n\n");
    
    // 创建表达式:5 + 3
    Expression* left1 = (Expression*)createNumberExpression(5);
    Expression* right1 = (Expression*)createNumberExpression(3);
    Expression* expr1 = (Expression*)createAddExpression(left1, right1);
    printf("表达式: 5 + 3\n");
    printf("结果: %d\n\n", expr1->interpret(expr1));
    
    // 创建表达式:10 - 2
    Expression* left2 = (Expression*)createNumberExpression(10);
    Expression* right2 = (Expression*)createNumberExpression(2);
    Expression* expr2 = (Expression*)createSubtractExpression(left2, right2);
    printf("表达式: 10 - 2\n");
    printf("结果: %d\n\n", expr2->interpret(expr2));
    
    // 创建表达式:4 * 2
    Expression* left3 = (Expression*)createNumberExpression(4);
    Expression* right3 = (Expression*)createNumberExpression(2);
    Expression* expr3 = (Expression*)createMultiplyExpression(left3, right3);
    printf("表达式: 4 * 2\n");
    printf("结果: %d\n\n", expr3->interpret(expr3));
    
    // 复杂表达式:(5 + 3) * 2
    Expression* complexLeft = (Expression*)createAddExpression(
        (Expression*)createNumberExpression(5),
        (Expression*)createNumberExpression(3)
    );
    Expression* complexRight = (Expression*)createNumberExpression(2);
    Expression* complexExpr = (Expression*)createMultiplyExpression(complexLeft, complexRight);
    printf("表达式: (5 + 3) * 2\n");
    printf("结果: %d\n\n", complexExpr->interpret(complexExpr));
    
    // 释放内存(简化版)
    free(left1);
    free(right1);
    free(expr1);
    free(left2);
    free(right2);
    free(expr2);
    free(left3);
    free(right3);
    free(expr3);
    free(complexLeft);
    free(complexRight);
    free(complexExpr);
    
    return 0;
}

编译运行:

bash 复制代码
gcc interpreter.c -o interpreter
./interpreter

4. 迭代器模式(Iterator Pattern)

通俗解释: 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。就像遥控器,可以顺序切换电视频道。

生活例子:

  • 遥控器:顺序切换频道
  • 书签:顺序浏览网页
  • 播放列表:顺序播放歌曲

适用场景:

  • 需要遍历集合
  • 需要统一遍历接口

C语言实现:

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

// ========== 迭代器接口 ==========
typedef struct {
    int (*hasNext)(void* self);      // 是否有下一个元素
    void* (*next)(void* self);       // 获取下一个元素
    void (*reset)(void* self);       // 重置迭代器
} Iterator;

// ========== 聚合接口 ==========
typedef struct {
    Iterator* (*createIterator)(void* self);  // 创建迭代器
    int size;                                  // 集合大小
} Aggregate;

// ========== 具体聚合:数组集合 ==========
typedef struct {
    Aggregate base;
    int* data;      // 数据数组
    int capacity;   // 容量
} ArrayCollection;

// ========== 具体迭代器:数组迭代器 ==========
typedef struct {
    Iterator base;
    ArrayCollection* collection;  // 关联的集合
    int currentIndex;             // 当前索引
} ArrayIterator;

int arrayIterator_hasNext(void* self) {
    ArrayIterator* it = (ArrayIterator*)self;
    return it->currentIndex < it->collection->base.size;
}

void* arrayIterator_next(void* self) {
    ArrayIterator* it = (ArrayIterator*)self;
    if (it->hasNext(it)) {
        void* item = &it->collection->data[it->currentIndex++];
        return item;
    }
    return NULL;
}

void arrayIterator_reset(void* self) {
    ArrayIterator* it = (ArrayIterator*)self;
    it->currentIndex = 0;
}

Iterator* arrayIterator_create(ArrayCollection* collection) {
    ArrayIterator* it = (ArrayIterator*)malloc(sizeof(ArrayIterator));
    it->base.hasNext = arrayIterator_hasNext;
    it->base.next = arrayIterator_next;
    it->base.reset = arrayIterator_reset;
    it->collection = collection;
    it->currentIndex = 0;
    return (Iterator*)it;
}

Iterator* arrayCollection_createIterator(void* self) {
    ArrayCollection* ac = (ArrayCollection*)self;
    return arrayIterator_create(ac);
}

ArrayCollection* createArrayCollection(int capacity) {
    ArrayCollection* ac = (ArrayCollection*)malloc(sizeof(ArrayCollection));
    ac->data = (int*)malloc(sizeof(int) * capacity);
    ac->capacity = capacity;
    ac->base.size = 0;
    ac->base.createIterator = arrayCollection_createIterator;
    return ac;
}

void arrayCollection_add(ArrayCollection* ac, int value) {
    if (ac->base.size < ac->capacity) {
        ac->data[ac->base.size++] = value;
    }
}

// ========== 客户端代码 ==========
void traverseCollection(Aggregate* aggregate) {
    printf("遍历集合:\n");
    Iterator* it = aggregate->createIterator(aggregate);
    
    int index = 0;
    while (it->hasNext(it)) {
        int* value = (int*)it->next(it);
        printf("  元素[%d]: %d\n", index++, *value);
    }
    
    free(it);
}

int main() {
    printf("=== 迭代器模式演示 ===\n\n");
    
    // 创建集合
    ArrayCollection* collection = createArrayCollection(10);
    
    // 添加元素
    arrayCollection_add(collection, 10);
    arrayCollection_add(collection, 20);
    arrayCollection_add(collection, 30);
    arrayCollection_add(collection, 40);
    arrayCollection_add(collection, 50);
    
    printf("集合大小: %d\n\n", collection->base.size);
    
    // 使用迭代器遍历
    traverseCollection((Aggregate*)collection);
    
    // 手动使用迭代器
    printf("\n手动遍历:\n");
    Iterator* it = collection->base.createIterator(collection);
    while (it->hasNext(it)) {
        int* value = (int*)it->next(it);
        printf("值: %d\n", *value);
    }
    
    // 重置迭代器
    printf("\n重置后再次遍历:\n");
    it->reset(it);
    while (it->hasNext(it)) {
        int* value = (int*)it->next(it);
        printf("值: %d\n", *value);
    }
    
    // 释放内存
    free(it);
    free(collection->data);
    free(collection);
    
    return 0;
}

编译运行:

bash 复制代码
gcc iterator.c -o iterator
./iterator

5. 中介者模式(Mediator Pattern)

通俗解释: 用一个中介对象来封装一系列对象的交互。就像聊天室,所有人通过聊天室交流,而不是直接互相联系。

生活例子:

  • 聊天室:所有人通过聊天室交流
  • 机场塔台:所有飞机通过塔台协调
  • 股票交易所:所有交易通过交易所进行

适用场景:

  • 对象之间有很多交互
  • 需要解耦对象之间的直接依赖

C语言实现:

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

// ========== 中介者接口 ==========
typedef struct Mediator {
    void (*sendMessage)(struct Mediator* self, const char* from, const char* to, const char* message);
} Mediator;

// ========== 同事接口 ==========
typedef struct Colleague {
    char name[50];
    Mediator* mediator;  // 中介者引用
    void (*send)(struct Colleague* self, const char* to, const char* message);
    void (*receive)(struct Colleague* self, const char* from, const char* message);
} Colleague;

void colleague_send(Colleague* self, const char* to, const char* message) {
    printf("%s 发送消息给 %s: %s\n", self->name, to, message);
    self->mediator->sendMessage(self->mediator, self->name, to, message);
}

void colleague_receive(Colleague* self, const char* from, const char* message) {
    printf("%s 收到来自 %s 的消息: %s\n", self->name, from, message);
}

// ========== 具体中介者:聊天室 ==========
typedef struct {
    Mediator base;
    Colleague* colleagues[10];  // 注册的同事
    int count;
} ChatRoom;

void chatRoom_sendMessage(Mediator* self, const char* from, const char* to, const char* message) {
    ChatRoom* cr = (ChatRoom*)self;
    
    // 查找接收者
    for (int i = 0; i < cr->count; i++) {
        if (strcmp(cr->colleagues[i]->name, to) == 0) {
            cr->colleagues[i]->receive(cr->colleagues[i], from, message);
            return;
        }
    }
    
    // 如果没找到接收者,可能是群发消息
    if (strcmp(to, "所有人") == 0) {
        printf("--- 群发消息 ---\n");
        for (int i = 0; i < cr->count; i++) {
            if (strcmp(cr->colleagues[i]->name, from) != 0) {
                cr->colleagues[i]->receive(cr->colleagues[i], from, message);
            }
        }
    } else {
        printf("错误:找不到用户 %s\n", to);
    }
}

ChatRoom* createChatRoom() {
    ChatRoom* cr = (ChatRoom*)malloc(sizeof(ChatRoom));
    cr->base.sendMessage = chatRoom_sendMessage;
    cr->count = 0;
    return cr;
}

void chatRoom_register(ChatRoom* cr, Colleague* colleague) {
    if (cr->count < 10) {
        cr->colleagues[cr->count++] = colleague;
        colleague->mediator = (Mediator*)cr;
        printf("%s 加入聊天室\n", colleague->name);
    }
}

// ========== 具体同事:用户 ==========
typedef struct {
    Colleague base;
} User;

User* createUser(const char* name) {
    User* user = (User*)malloc(sizeof(User));
    strcpy(user->base.name, name);
    user->base.send = colleague_send;
    user->base.receive = colleague_receive;
    user->base.mediator = NULL;
    return user;
}

int main() {
    printf("=== 中介者模式演示 ===\n\n");
    
    // 创建中介者(聊天室)
    ChatRoom* chatRoom = createChatRoom();
    
    // 创建用户
    User* alice = createUser("Alice");
    User* bob = createUser("Bob");
    User* charlie = createUser("Charlie");
    
    // 注册到聊天室
    chatRoom_register(chatRoom, (Colleague*)alice);
    chatRoom_register(chatRoom, (Colleague*)bob);
    chatRoom_register(chatRoom, (Colleague*)charlie);
    
    printf("\n--- 开始聊天 ---\n");
    
    // 用户通过中介者(聊天室)发送消息
    alice->base.send((Colleague*)alice, "Bob", "你好,Bob!");
    printf("\n");
    
    bob->base.send((Colleague*)bob, "Alice", "你好,Alice!");
    printf("\n");
    
    charlie->base.send((Colleague*)charlie, "所有人", "大家好!");
    
    // 释放内存
    free(alice);
    free(bob);
    free(charlie);
    free(chatRoom);
    
    return 0;
}

编译运行:

bash 复制代码
gcc mediator.c -o mediator
./mediator

6. 备忘录模式(Memento Pattern)

通俗解释: 在不破坏封装性的前提下,捕获对象的内部状态,并在对象之外保存这个状态。就像游戏存档,可以保存和恢复游戏状态。

生活例子:

  • 游戏存档:保存游戏状态,可以恢复
  • 撤销功能:保存操作历史,可以撤销
  • 数据库事务:保存事务状态,可以回滚

适用场景:

  • 需要保存对象状态
  • 需要支持撤销功能

C语言实现:

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

// ========== 备忘录:保存状态 ==========
typedef struct {
    int level;      // 关卡
    int score;      // 分数
    int health;     // 生命值
    char state[100]; // 状态描述
} Memento;

Memento* createMemento(int level, int score, int health, const char* state) {
    Memento* m = (Memento*)malloc(sizeof(Memento));
    m->level = level;
    m->score = score;
    m->health = health;
    strcpy(m->state, state);
    return m;
}

void memento_display(Memento* m) {
    printf("=== 存档信息 ===\n");
    printf("关卡: %d\n", m->level);
    printf("分数: %d\n", m->score);
    printf("生命值: %d\n", m->health);
    printf("状态: %s\n", m->state);
    printf("==============\n");
}

// ========== 原发器:游戏角色 ==========
// 需要保存状态的对象
typedef struct {
    int level;
    int score;
    int health;
    char state[100];
    
    Memento* (*save)(void* self);           // 保存状态
    void (*restore)(void* self, Memento* m); // 恢复状态
    void (*play)(void* self);               // 游戏操作
    void (*display)(void* self);            // 显示状态
} GameCharacter;

Memento* gameCharacter_save(void* self) {
    GameCharacter* gc = (GameCharacter*)self;
    sprintf(gc->state, "关卡%d-分数%d-生命%d", gc->level, gc->score, gc->health);
    return createMemento(gc->level, gc->score, gc->health, gc->state);
}

void gameCharacter_restore(void* self, Memento* m) {
    GameCharacter* gc = (GameCharacter*)self;
    gc->level = m->level;
    gc->score = m->score;
    gc->health = m->health;
    strcpy(gc->state, m->state);
    printf("恢复游戏状态\n");
}

void gameCharacter_play(void* self) {
    GameCharacter* gc = (GameCharacter*)self;
    gc->level++;
    gc->score += 100;
    gc->health -= 10;
    sprintf(gc->state, "关卡%d-分数%d-生命%d", gc->level, gc->score, gc->health);
    printf("游戏进行中...\n");
}

void gameCharacter_display(void* self) {
    GameCharacter* gc = (GameCharacter*)self;
    printf("=== 当前游戏状态 ===\n");
    printf("关卡: %d\n", gc->level);
    printf("分数: %d\n", gc->score);
    printf("生命值: %d\n", gc->health);
    printf("状态: %s\n", gc->state);
    printf("==================\n");
}

GameCharacter* createGameCharacter() {
    GameCharacter* gc = (GameCharacter*)malloc(sizeof(GameCharacter));
    gc->level = 1;
    gc->score = 0;
    gc->health = 100;
    strcpy(gc->state, "初始状态");
    gc->save = gameCharacter_save;
    gc->restore = gameCharacter_restore;
    gc->play = gameCharacter_play;
    gc->display = gameCharacter_display;
    return gc;
}

// ========== 管理者:存档管理器 ==========
// 负责保存和管理备忘录
typedef struct {
    Memento* mementos[10];  // 存档列表
    int count;
} Caretaker;

Caretaker* createCaretaker() {
    Caretaker* ct = (Caretaker*)malloc(sizeof(Caretaker));
    ct->count = 0;
    return ct;
}

void caretaker_save(Caretaker* ct, Memento* m) {
    if (ct->count < 10) {
        ct->mementos[ct->count++] = m;
        printf("存档成功(存档%d)\n", ct->count);
    } else {
        printf("存档已满\n");
    }
}

Memento* caretaker_load(Caretaker* ct, int index) {
    if (index >= 1 && index <= ct->count) {
        printf("加载存档%d\n", index);
        return ct->mementos[index - 1];
    }
    printf("存档不存在\n");
    return NULL;
}

int main() {
    printf("=== 备忘录模式演示 ===\n\n");
    
    // 创建游戏角色
    GameCharacter* character = createGameCharacter();
    character->display(character);
    
    // 创建存档管理器
    Caretaker* caretaker = createCaretaker();
    
    // 保存初始状态
    printf("\n--- 保存初始状态 ---\n");
    Memento* save1 = character->save(character);
    caretaker_save(caretaker, save1);
    
    // 游戏进行
    printf("\n--- 游戏进行 ---\n");
    character->play(character);
    character->display(character);
    
    // 保存进度
    printf("\n--- 保存进度1 ---\n");
    Memento* save2 = character->save(character);
    caretaker_save(caretaker, save2);
    
    // 继续游戏
    printf("\n--- 继续游戏 ---\n");
    character->play(character);
    character->display(character);
    
    // 恢复存档1
    printf("\n--- 恢复到存档1 ---\n");
    Memento* loaded = caretaker_load(caretaker, 1);
    if (loaded) {
        memento_display(loaded);
        character->restore(character, loaded);
        character->display(character);
    }
    
    // 释放内存(简化版)
    free(character);
    for (int i = 0; i < caretaker->count; i++) {
        free(caretaker->mementos[i]);
    }
    free(caretaker);
    
    return 0;
}

编译运行:

bash 复制代码
gcc memento.c -o memento
./memento

7. 观察者模式(Observer Pattern)

通俗解释: 定义对象间一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。就像订阅报纸,报纸更新时,所有订阅者都会收到。

生活例子:

  • 订阅报纸:报纸更新,订阅者收到
  • 微信朋友圈:发朋友圈,好友收到通知
  • 股票价格:价格变化,所有关注者收到通知

适用场景:

  • 一个对象状态改变需要通知多个对象
  • 需要解耦观察者和被观察者

C语言实现:

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

// ========== 观察者接口 ==========
typedef struct Observer {
    char name[50];
    void (*update)(struct Observer* self, const char* message);  // 更新函数
} Observer;

// ========== 主题接口 ==========
typedef struct Subject {
    Observer* observers[10];  // 观察者列表
    int observerCount;         // 观察者数量
    
    void (*attach)(struct Subject* self, Observer* observer);    // 添加观察者
    void (*detach)(struct Subject* self, Observer* observer);    // 移除观察者
    void (*notify)(struct Subject* self, const char* message);   // 通知观察者
} Subject;

void subject_attach(Subject* self, Observer* observer) {
    if (self->observerCount < 10) {
        self->observers[self->observerCount++] = observer;
        printf("%s 订阅了主题\n", observer->name);
    }
}

void subject_detach(Subject* self, Observer* observer) {
    for (int i = 0; i < self->observerCount; i++) {
        if (self->observers[i] == observer) {
            // 移除观察者
            for (int j = i; j < self->observerCount - 1; j++) {
                self->observers[j] = self->observers[j + 1];
            }
            self->observerCount--;
            printf("%s 取消订阅\n", observer->name);
            return;
        }
    }
}

void subject_notify(Subject* self, const char* message) {
    printf("\n--- 通知所有观察者 ---\n");
    for (int i = 0; i < self->observerCount; i++) {
        self->observers[i]->update(self->observers[i], message);
    }
}

// ========== 具体主题:新闻发布者 ==========
typedef struct {
    Subject base;
    char news[200];  // 新闻内容
} NewsPublisher;

NewsPublisher* createNewsPublisher() {
    NewsPublisher* np = (NewsPublisher*)malloc(sizeof(NewsPublisher));
    np->base.attach = subject_attach;
    np->base.detach = subject_detach;
    np->base.notify = subject_notify;
    np->base.observerCount = 0;
    strcpy(np->news, "");
    return np;
}

void newsPublisher_publish(NewsPublisher* np, const char* news) {
    strcpy(np->news, news);
    printf("发布新闻: %s\n", news);
    np->base.notify(&np->base, news);
}

// ========== 具体观察者:订阅者 ==========
typedef struct {
    Observer base;
} NewsSubscriber;

void newsSubscriber_update(Observer* self, const char* message) {
    printf("%s 收到新闻: %s\n", self->name, message);
}

NewsSubscriber* createNewsSubscriber(const char* name) {
    NewsSubscriber* ns = (NewsSubscriber*)malloc(sizeof(NewsSubscriber));
    strcpy(ns->base.name, name);
    ns->base.update = newsSubscriber_update;
    return ns;
}

int main() {
    printf("=== 观察者模式演示 ===\n\n");
    
    // 创建主题(新闻发布者)
    NewsPublisher* publisher = createNewsPublisher();
    
    // 创建观察者(订阅者)
    NewsSubscriber* subscriber1 = createNewsSubscriber("张三");
    NewsSubscriber* subscriber2 = createNewsSubscriber("李四");
    NewsSubscriber* subscriber3 = createNewsSubscriber("王五");
    
    // 订阅
    publisher->base.attach(&publisher->base, (Observer*)subscriber1);
    publisher->base.attach(&publisher->base, (Observer*)subscriber2);
    publisher->base.attach(&publisher->base, (Observer*)subscriber3);
    
    // 发布新闻
    printf("\n");
    newsPublisher_publish(publisher, "今天天气很好!");
    
    // 取消订阅
    printf("\n");
    publisher->base.detach(&publisher->base, (Observer*)subscriber2);
    
    // 再次发布新闻
    printf("\n");
    newsPublisher_publish(publisher, "明天要下雨了!");
    
    // 释放内存
    free(publisher);
    free(subscriber1);
    free(subscriber2);
    free(subscriber3);
    
    return 0;
}

编译运行:

bash 复制代码
gcc observer.c -o observer
./observer

8. 状态模式(State Pattern)

通俗解释: 允许对象在内部状态改变时改变它的行为。就像自动售货机,不同状态(有货/无货)有不同的行为。

生活例子:

  • 自动售货机:有货/无货状态,行为不同
  • 交通灯:红灯/绿灯/黄灯状态
  • 游戏角色:正常/受伤/死亡状态

适用场景:

  • 对象行为依赖于状态
  • 需要根据状态改变行为

C语言实现:

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

// ========== 状态接口 ==========
typedef struct State {
    void (*handle)(void* self);  // 处理函数
    char name[50];
} State;

// ========== 上下文:自动售货机 ==========
typedef struct {
    State* currentState;  // 当前状态
    int itemCount;        // 商品数量
    void (*request)(void* self);      // 请求操作
    void (*setState)(void* self, State* state);  // 设置状态
} VendingMachine;

void vendingMachine_request(void* self) {
    VendingMachine* vm = (VendingMachine*)self;
    printf("当前状态: %s\n", vm->currentState->name);
    vm->currentState->handle(vm->currentState);
}

void vendingMachine_setState(void* self, State* state) {
    VendingMachine* vm = (VendingMachine*)self;
    vm->currentState = state;
    printf("状态切换为: %s\n", state->name);
}

VendingMachine* createVendingMachine() {
    VendingMachine* vm = (VendingMachine*)malloc(sizeof(VendingMachine));
    vm->itemCount = 0;
    vm->request = vendingMachine_request;
    vm->setState = vendingMachine_setState;
    return vm;
}

// ========== 具体状态:有货状态 ==========
typedef struct {
    State base;
    VendingMachine* machine;
} HasItemState;

void hasItemState_handle(void* self) {
    HasItemState* state = (HasItemState*)self;
    printf("有货状态:可以购买\n");
    state->machine->itemCount--;
    printf("售出一件商品,剩余: %d\n", state->machine->itemCount);
    
    // 如果商品售完,切换到无货状态
    if (state->machine->itemCount == 0) {
        // 这里简化处理,实际应该通过状态管理器切换
        printf("商品售完,切换到无货状态\n");
    }
}

HasItemState* createHasItemState(VendingMachine* machine) {
    HasItemState* state = (HasItemState*)malloc(sizeof(HasItemState));
    strcpy(state->base.name, "有货");
    state->base.handle = hasItemState_handle;
    state->machine = machine;
    return state;
}

// ========== 具体状态:无货状态 ==========
typedef struct {
    State base;
    VendingMachine* machine;
} NoItemState;

void noItemState_handle(void* self) {
    NoItemState* state = (NoItemState*)self;
    printf("无货状态:无法购买,请补货\n");
}

NoItemState* createNoItemState(VendingMachine* machine) {
    NoItemState* state = (NoItemState*)malloc(sizeof(NoItemState));
    strcpy(state->base.name, "无货");
    state->base.handle = noItemState_handle;
    state->machine = machine;
    return state;
}

int main() {
    printf("=== 状态模式演示 ===\n\n");
    
    // 创建自动售货机
    VendingMachine* machine = createVendingMachine();
    machine->itemCount = 3;  // 初始有3件商品
    
    // 创建状态
    HasItemState* hasItem = createHasItemState(machine);
    NoItemState* noItem = createNoItemState(machine);
    
    // 设置初始状态
    machine->setState(machine, (State*)hasItem);
    
    // 购买商品
    printf("\n--- 购买商品1 ---\n");
    machine->request(machine);
    
    printf("\n--- 购买商品2 ---\n");
    machine->request(machine);
    
    printf("\n--- 购买商品3 ---\n");
    machine->request(machine);
    
    // 切换到无货状态
    printf("\n--- 商品售完 ---\n");
    machine->setState(machine, (State*)noItem);
    
    // 尝试购买(无货)
    printf("\n--- 尝试购买(无货) ---\n");
    machine->request(machine);
    
    // 释放内存
    free(machine);
    free(hasItem);
    free(noItem);
    
    return 0;
}

编译运行:

bash 复制代码
gcc state.c -o state
./state

9. 策略模式(Strategy Pattern)

通俗解释: 定义一系列算法,把它们封装起来,并且使它们可以互换。就像支付方式,可以用支付宝、微信、信用卡等不同策略。

生活例子:

  • 支付方式:支付宝、微信、信用卡等不同策略
  • 排序算法:快速排序、冒泡排序、归并排序等
  • 导航方式:步行、开车、公交等不同路线策略

适用场景:

  • 需要在运行时选择算法
  • 有多个相似的类,只是行为不同

C语言实现:

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

// ========== 策略接口:支付策略 ==========
typedef struct {
    void (*pay)(void* self, double amount);  // 支付函数
    char name[50];
} PaymentStrategy;

// ========== 具体策略:支付宝支付 ==========
typedef struct {
    PaymentStrategy base;
} AlipayStrategy;

void alipayStrategy_pay(void* self, double amount) {
    printf("使用支付宝支付: %.2f 元\n", amount);
    printf("跳转到支付宝支付页面...\n");
    printf("支付成功!\n");
}

AlipayStrategy* createAlipayStrategy() {
    AlipayStrategy* strategy = (AlipayStrategy*)malloc(sizeof(AlipayStrategy));
    strcpy(strategy->base.name, "支付宝");
    strategy->base.pay = alipayStrategy_pay;
    return strategy;
}

// ========== 具体策略:微信支付 ==========
typedef struct {
    PaymentStrategy base;
} WeChatStrategy;

void weChatStrategy_pay(void* self, double amount) {
    printf("使用微信支付: %.2f 元\n", amount);
    printf("打开微信支付...\n");
    printf("支付成功!\n");
}

WeChatStrategy* createWeChatStrategy() {
    WeChatStrategy* strategy = (WeChatStrategy*)malloc(sizeof(WeChatStrategy));
    strcpy(strategy->base.name, "微信");
    strategy->base.pay = weChatStrategy_pay;
    return strategy;
}

// ========== 具体策略:信用卡支付 ==========
typedef struct {
    PaymentStrategy base;
} CreditCardStrategy;

void creditCardStrategy_pay(void* self, double amount) {
    printf("使用信用卡支付: %.2f 元\n", amount);
    printf("输入信用卡信息...\n");
    printf("支付成功!\n");
}

CreditCardStrategy* createCreditCardStrategy() {
    CreditCardStrategy* strategy = (CreditCardStrategy*)malloc(sizeof(CreditCardStrategy));
    strcpy(strategy->base.name, "信用卡");
    strategy->base.pay = creditCardStrategy_pay;
    return strategy;
}

// ========== 上下文:购物车 ==========
typedef struct {
    PaymentStrategy* strategy;  // 当前支付策略
    double total;               // 总金额
    
    void (*setPaymentStrategy)(void* self, PaymentStrategy* strategy);  // 设置支付策略
    void (*checkout)(void* self);  // 结账
    void (*addItem)(void* self, double price);  // 添加商品
} ShoppingCart;

void shoppingCart_setPaymentStrategy(void* self, PaymentStrategy* strategy) {
    ShoppingCart* cart = (ShoppingCart*)self;
    cart->strategy = strategy;
    printf("设置支付方式为: %s\n", strategy->name);
}

void shoppingCart_checkout(void* self) {
    ShoppingCart* cart = (ShoppingCart*)self;
    if (cart->strategy == NULL) {
        printf("错误:未设置支付方式\n");
        return;
    }
    printf("\n=== 结账 ===\n");
    printf("总金额: %.2f 元\n", cart->total);
    cart->strategy->pay(cart->strategy, cart->total);
    printf("===========\n\n");
}

void shoppingCart_addItem(void* self, double price) {
    ShoppingCart* cart = (ShoppingCart*)self;
    cart->total += price;
    printf("添加商品,价格: %.2f 元,总计: %.2f 元\n", price, cart->total);
}

ShoppingCart* createShoppingCart() {
    ShoppingCart* cart = (ShoppingCart*)malloc(sizeof(ShoppingCart));
    cart->strategy = NULL;
    cart->total = 0.0;
    cart->setPaymentStrategy = shoppingCart_setPaymentStrategy;
    cart->checkout = shoppingCart_checkout;
    cart->addItem = shoppingCart_addItem;
    return cart;
}

int main() {
    printf("=== 策略模式演示 ===\n\n");
    
    // 创建购物车
    ShoppingCart* cart = createShoppingCart();
    
    // 添加商品
    cart->addItem(cart, 100.0);
    cart->addItem(cart, 50.0);
    cart->addItem(cart, 30.0);
    
    // 使用不同的支付策略
    printf("\n--- 使用支付宝支付 ---\n");
    AlipayStrategy* alipay = createAlipayStrategy();
    cart->setPaymentStrategy(cart, (PaymentStrategy*)alipay);
    cart->checkout(cart);
    
    // 重置购物车
    cart->total = 180.0;
    
    printf("--- 使用微信支付 ---\n");
    WeChatStrategy* wechat = createWeChatStrategy();
    cart->setPaymentStrategy(cart, (PaymentStrategy*)wechat);
    cart->checkout(cart);
    
    // 重置购物车
    cart->total = 180.0;
    
    printf("--- 使用信用卡支付 ---\n");
    CreditCardStrategy* credit = createCreditCardStrategy();
    cart->setPaymentStrategy(cart, (PaymentStrategy*)credit);
    cart->checkout(cart);
    
    // 释放内存
    free(cart);
    free(alipay);
    free(wechat);
    free(credit);
    
    return 0;
}

编译运行:

bash 复制代码
gcc strategy.c -o strategy
./strategy

10. 模板方法模式(Template Method Pattern)

通俗解释: 定义一个操作中算法的骨架,而将一些步骤延迟到子类中。就像做菜,步骤固定(洗菜、切菜、炒菜),但具体做法可以不同。

生活例子:

  • 做菜:步骤固定,但具体做法不同
  • 考试:流程固定(发卷、答题、收卷),但题目不同
  • 银行开户:流程固定,但不同银行细节不同

适用场景:

  • 有多个类有相似的算法结构
  • 需要控制算法的流程

C语言实现:

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

// ========== 抽象类:饮料制作模板 ==========
typedef struct {
    void (*brew)(void* self);        // 冲泡(抽象方法)
    void (*addCondiments)(void* self); // 添加调料(抽象方法)
    void (*makeBeverage)(void* self);  // 制作饮料(模板方法)
} BeverageTemplate;

// 模板方法:定义算法骨架
void beverageTemplate_makeBeverage(void* self) {
    BeverageTemplate* bt = (BeverageTemplate*)self;
    printf("=== 开始制作饮料 ===\n");
    printf("步骤1: 烧水\n");
    printf("步骤2: ");
    bt->brew(bt);  // 调用具体实现
    printf("步骤3: 倒入杯子\n");
    printf("步骤4: ");
    bt->addCondiments(bt);  // 调用具体实现
    printf("步骤5: 完成\n");
    printf("==================\n\n");
}

// ========== 具体类:咖啡 ==========
typedef struct {
    BeverageTemplate base;
} Coffee;

void coffee_brew(void* self) {
    printf("冲泡咖啡\n");
}

void coffee_addCondiments(void* self) {
    printf("添加糖和牛奶\n");
}

Coffee* createCoffee() {
    Coffee* coffee = (Coffee*)malloc(sizeof(Coffee));
    coffee->base.brew = coffee_brew;
    coffee->base.addCondiments = coffee_addCondiments;
    coffee->base.makeBeverage = beverageTemplate_makeBeverage;
    return coffee;
}

// ========== 具体类:茶 ==========
typedef struct {
    BeverageTemplate base;
} Tea;

void tea_brew(void* self) {
    printf("冲泡茶叶\n");
}

void tea_addCondiments(void* self) {
    printf("添加柠檬\n");
}

Tea* createTea() {
    Tea* tea = (Tea*)malloc(sizeof(Tea));
    tea->base.brew = tea_brew;
    tea->base.addCondiments = tea_addCondiments;
    tea->base.makeBeverage = beverageTemplate_makeBeverage;
    return tea;
}

// ========== 具体类:纯咖啡(不添加调料) ==========
typedef struct {
    BeverageTemplate base;
} BlackCoffee;

void blackCoffee_brew(void* self) {
    printf("冲泡咖啡\n");
}

void blackCoffee_addCondiments(void* self) {
    printf("不添加任何调料(纯咖啡)\n");
}

BlackCoffee* createBlackCoffee() {
    BlackCoffee* bc = (BlackCoffee*)malloc(sizeof(BlackCoffee));
    bc->base.brew = blackCoffee_brew;
    bc->base.addCondiments = blackCoffee_addCondiments;
    bc->base.makeBeverage = beverageTemplate_makeBeverage;
    return bc;
}

int main() {
    printf("=== 模板方法模式演示 ===\n\n");
    
    // 制作咖啡
    Coffee* coffee = createCoffee();
    coffee->base.makeBeverage(&coffee->base);
    
    // 制作茶
    Tea* tea = createTea();
    tea->base.makeBeverage(&tea->base);
    
    // 制作纯咖啡
    BlackCoffee* blackCoffee = createBlackCoffee();
    blackCoffee->base.makeBeverage(&blackCoffee->base);
    
    // 释放内存
    free(coffee);
    free(tea);
    free(blackCoffee);
    
    return 0;
}

编译运行:

bash 复制代码
gcc template_method.c -o template_method
./template_method

11. 访问者模式(Visitor Pattern)

通俗解释: 表示一个作用于某对象结构中的各元素的操作,可以在不改变各元素类的前提下定义作用于这些元素的新操作。就像医生访问病人,对不同病人做不同检查。

生活例子:

  • 医生访问病人:对不同病人做不同检查
  • 税务审计:对不同公司做不同审计
  • 编译器:对不同语法节点做不同处理

适用场景:

  • 需要对对象结构中的元素执行不同操作
  • 需要在不改变元素类的情况下添加新操作

C语言实现:

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

// ========== 访问者接口 ==========
typedef struct Visitor {
    void (*visitElementA)(struct Visitor* self, void* element);  // 访问元素A
    void (*visitElementB)(struct Visitor* self, void* element);  // 访问元素B
} Visitor;

// ========== 元素接口 ==========
typedef struct Element {
    void (*accept)(void* self, Visitor* visitor);  // 接受访问者
    char name[50];
} Element;

// ========== 具体元素A ==========
typedef struct {
    Element base;
    int valueA;
} ConcreteElementA;

void elementA_accept(void* self, Visitor* visitor) {
    ConcreteElementA* elem = (ConcreteElementA*)self;
    printf("%s 接受访问\n", elem->base.name);
    visitor->visitElementA(visitor, elem);
}

ConcreteElementA* createElementA(const char* name, int value) {
    ConcreteElementA* elem = (ConcreteElementA*)malloc(sizeof(ConcreteElementA));
    strcpy(elem->base.name, name);
    elem->base.accept = elementA_accept;
    elem->valueA = value;
    return elem;
}

// ========== 具体元素B ==========
typedef struct {
    Element base;
    char valueB[50];
} ConcreteElementB;

void elementB_accept(void* self, Visitor* visitor) {
    ConcreteElementB* elem = (ConcreteElementB*)self;
    printf("%s 接受访问\n", elem->base.name);
    visitor->visitElementB(visitor, elem);
}

ConcreteElementB* createElementB(const char* name, const char* value) {
    ConcreteElementB* elem = (ConcreteElementB*)malloc(sizeof(ConcreteElementB));
    strcpy(elem->base.name, name);
    elem->base.accept = elementB_accept;
    strcpy(elem->valueB, value);
    return elem;
}

// ========== 具体访问者:操作1 ==========
typedef struct {
    Visitor base;
} ConcreteVisitor1;

void visitor1_visitElementA(Visitor* self, void* element) {
    ConcreteElementA* elem = (ConcreteElementA*)element;
    printf("访问者1 访问元素A: %s,执行操作1,值: %d\n", elem->base.name, elem->valueA);
}

void visitor1_visitElementB(Visitor* self, void* element) {
    ConcreteElementB* elem = (ConcreteElementB*)element;
    printf("访问者1 访问元素B: %s,执行操作1,值: %s\n", elem->base.name, elem->valueB);
}

ConcreteVisitor1* createVisitor1() {
    ConcreteVisitor1* v = (ConcreteVisitor1*)malloc(sizeof(ConcreteVisitor1));
    v->base.visitElementA = visitor1_visitElementA;
    v->base.visitElementB = visitor1_visitElementB;
    return v;
}

// ========== 具体访问者:操作2 ==========
typedef struct {
    Visitor base;
} ConcreteVisitor2;

void visitor2_visitElementA(Visitor* self, void* element) {
    ConcreteElementA* elem = (ConcreteElementA*)element;
    printf("访问者2 访问元素A: %s,执行操作2,值: %d\n", elem->base.name, elem->valueA);
}

void visitor2_visitElementB(Visitor* self, void* element) {
    ConcreteElementB* elem = (ConcreteElementB*)element;
    printf("访问者2 访问元素B: %s,执行操作2,值: %s\n", elem->base.name, elem->valueB);
}

ConcreteVisitor2* createVisitor2() {
    ConcreteVisitor2* v = (ConcreteVisitor2*)malloc(sizeof(ConcreteVisitor2));
    v->base.visitElementA = visitor2_visitElementA;
    v->base.visitElementB = visitor2_visitElementB;
    return v;
}

// ========== 对象结构 ==========
typedef struct {
    Element* elements[10];
    int count;
    void (*add)(void* self, Element* element);
    void (*accept)(void* self, Visitor* visitor);
} ObjectStructure;

void objectStructure_add(void* self, Element* element) {
    ObjectStructure* os = (ObjectStructure*)self;
    if (os->count < 10) {
        os->elements[os->count++] = element;
    }
}

void objectStructure_accept(void* self, Visitor* visitor) {
    ObjectStructure* os = (ObjectStructure*)self;
    printf("\n=== 访问对象结构 ===\n");
    for (int i = 0; i < os->count; i++) {
        os->elements[i]->accept(os->elements[i], visitor);
    }
    printf("==================\n\n");
}

ObjectStructure* createObjectStructure() {
    ObjectStructure* os = (ObjectStructure*)malloc(sizeof(ObjectStructure));
    os->count = 0;
    os->add = objectStructure_add;
    os->accept = objectStructure_accept;
    return os;
}

int main() {
    printf("=== 访问者模式演示 ===\n\n");
    
    // 创建元素
    ConcreteElementA* elemA = createElementA("元素A", 100);
    ConcreteElementB* elemB = createElementB("元素B", "Hello");
    
    // 创建对象结构
    ObjectStructure* structure = createObjectStructure();
    structure->add(structure, (Element*)elemA);
    structure->add(structure, (Element*)elemB);
    
    // 使用访问者1访问
    ConcreteVisitor1* visitor1 = createVisitor1();
    structure->accept(structure, (Visitor*)visitor1);
    
    // 使用访问者2访问
    ConcreteVisitor2* visitor2 = createVisitor2();
    structure->accept(structure, (Visitor*)visitor2);
    
    // 释放内存
    free(elemA);
    free(elemB);
    free(structure);
    free(visitor1);
    free(visitor2);
    
    return 0;
}

编译运行:

bash 复制代码
gcc visitor.c -o visitor
./visitor

总结:行为型模式

行为型模式帮助我们管理对象之间的通信和职责:

  • 责任链模式:将请求沿着处理者链传递
  • 命令模式:将请求封装成对象
  • 解释器模式:定义语言的文法并解释
  • 迭代器模式:顺序访问集合元素
  • 中介者模式:封装对象间的交互
  • 备忘录模式:保存和恢复对象状态
  • 观察者模式:一对多的依赖关系
  • 状态模式:根据状态改变行为
  • 策略模式:封装可互换的算法
  • 模板方法模式:定义算法骨架
  • 访问者模式:在不改变元素类的前提下定义新操作

每种模式都解决了不同的行为问题,让代码更灵活、更易维护。


完整总结:23种设计模式

创建型模式(5个)

  1. 单例模式
  2. 工厂方法模式
  3. 抽象工厂模式
  4. 建造者模式
  5. 原型模式

结构型模式(7个)

  1. 适配器模式
  2. 桥接模式
  3. 组合模式
  4. 装饰器模式
  5. 外观模式
  6. 享元模式
  7. 代理模式

行为型模式(11个)

  1. 责任链模式
  2. 命令模式
  3. 解释器模式
  4. 迭代器模式
  5. 中介者模式
  6. 备忘录模式
  7. 观察者模式
  8. 状态模式
  9. 策略模式
  10. 模板方法模式
  11. 访问者模式

所有模式都遵循7大设计原则,帮助我们写出更好的代码!

相关推荐
傻啦嘿哟1 小时前
Python高效实现Excel与TXT文本文件数据转换指南
开发语言·python·excel
七宝大爷1 小时前
第一个CUDA程序:从向量加法开始
android·java·开发语言
木心爱编程1 小时前
Qt C++ 插件开发指南:插件架构设计与动态加载实战
开发语言·c++·qt
__万波__1 小时前
二十三种设计模式(十一)--享元模式
java·设计模式·享元模式
有什么东东1 小时前
redis实现店铺类型查看
java·开发语言·redis
AAIshangyanxiu1 小时前
基于R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析
开发语言·机器学习·r语言·生态遥感·空间预测
LinHenrY12271 小时前
初识C语言(数据在内存中的存储)
c语言·开发语言·算法
by__csdn1 小时前
javascript 性能优化实战:异步和延迟加载
开发语言·前端·javascript·vue.js·性能优化·typescript·ecmascript