设计模式专题之C语言-抽象工厂模式

1.简介

抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建一系列相关或依赖对象,而无需指定它们的具体类。这个模式通过组合多个工厂类,实现了对产品族的创建。

在C语言中,由于没有面向对象的特性(如类和继承),我们通过结构体和函数指针来模拟实现抽象工厂模式。

2.通俗讲解

想象你在不同的汽车制造厂订购汽车。每个工厂可以生产不同的汽车部件(比如发动机、轮胎),而这些部件都属于同一个品牌。你可能会去“品牌A”的工厂订购发动机和轮胎,也可能去“品牌B”的工厂订购相同的部件,但这些部件的具体实现细节不同。

抽象工厂模式就像一个工厂的集合,每个工厂可以生产属于自己品牌的一组产品,而你可以通过抽象工厂来获得这些工厂提供的产品。

3.实战

3.1.代码

#include <stdio.h>

/*
1. 定义产品接口
首先,我们定义抽象产品接口,包括Engine(发动机)和Tire(轮胎)。
*/
// 定义抽象产品接口 Engine
typedef struct Engine {
    void (*start)(void);
} Engine;

// 定义抽象产品接口 Tire
typedef struct Tire {
    void (*roll)(void);
} Tire;

/*
2. 实现具体产品
接下来,我们为两个品牌A和B分别实现具体的产品(发动机和轮胎)。
*/
// 品牌A的具体实现
void startEngineA() {
    printf("Engine A is starting...\n");
}

void rollTireA() {
    printf("Tire A is rolling...\n");
}

Engine* createEngineA() {
    static Engine engineA = { startEngineA };
    return &engineA;
}

Tire* createTireA() {
    static Tire tireA = { rollTireA };
    return &tireA;
}

// 品牌B的具体实现
void startEngineB() {
    printf("Engine B is starting...\n");
}

void rollTireB() {
    printf("Tire B is rolling...\n");
}

Engine* createEngineB() {
    static Engine engineB = { startEngineB };
    return &engineB;
}

Tire* createTireB() {
    static Tire tireB = { rollTireB };
    return &tireB;
}

/*
3. 定义抽象工厂接口
我们定义一个抽象工厂接口,它包含了创建产品的方法。
*/
// 抽象工厂接口
typedef struct CarFactory {
    Engine* (*createEngine)(void);
    Tire* (*createTire)(void);
} CarFactory;

/*
4. 实现具体工厂
我们为品牌A和品牌B分别实现具体的工厂,它们提供创建对应产品的功能。
*/
// 品牌A的工厂实现
CarFactory* createFactoryA() {
    static CarFactory factoryA = { createEngineA, createTireA };
    return &factoryA;
}

// 品牌B的工厂实现
CarFactory* createFactoryB() {
    static CarFactory factoryB = { createEngineB, createTireB };
    return &factoryB;
}

/*
5. 编写客户端代码
最后,我们编写客户端代码,通过选择不同的工厂来创建和使用产品。
*/
int main() {
    // 选择品牌A的工厂
    CarFactory* factoryA = createFactoryA();
    Engine* engineA = factoryA->createEngine();
    Tire* tireA = factoryA->createTire();

    // 运行品牌A的产品
    engineA->start();
    tireA->roll();

    // 选择品牌B的工厂
    CarFactory* factoryB = createFactoryB();
    Engine* engineB = factoryB->createEngine();
    Tire* tireB = factoryB->createTire();

    // 运行品牌B的产品
    engineB->start();
    tireB->roll();

    return 0;
}

3.2.代码解析

  • CarFactory 是抽象工厂接口,定义了创建 Engine 和 Tire 的方法。
  • createFactoryA 和 createFactoryB 是两个具体的工厂函数,分别生成品牌A和品牌B的产品。
  • 在 main 函数中,通过选择不同的工厂,我们得到了品牌A和品牌B的产品,并使用它们。

3.3.代码运行

Engine A is starting...
Tire A is rolling...
Engine B is starting...
Tire B is rolling...

3.4.结果分析

通过这个例子,我们可以看到抽象工厂模式的威力。客户端代码只需要知道自己要使用哪个品牌的工厂,而不需要关心具体的产品实现细节。这使得代码更具扩展性和可维护性。当我们需要新增品牌时,只需添加新的具体工厂和产品,而无需修改客户端代码。

4.总结

核心思想:

  • 抽象工厂接口定义了创建一组相关对象的方法。每个具体工厂实现了这些方法来生成特定的产品。
  • 具体工厂类负责实现抽象工厂接口,创建一组相关的具体产品(如发动机和轮胎)。
  • 客户端代码通过使用具体工厂,创建所需的产品对象,但无需关心具体实现细节。

优点:

  • 产品族的一致性:抽象工厂模式确保同一工厂生成的产品可以协同工作,避免了不同产品之间的兼容性问题。
  • 解耦性:客户端与具体产品的实现细节解耦,便于扩展和维护。新增产品族时,只需添加相应的具体工厂,不必修改客户端代码。

缺点

  • 扩展困难:如果需要增加新的产品类型,必须修改抽象工厂接口及所有具体工厂的实现,这对扩展有一定的挑战。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值