C++设计模式之工厂方法模式:以家具生产为例

在日常生活中,我们使用的椅子、桌子等家具,可能来自不同的生产厂家------有的工厂专门生产实木家具,有的专注于塑料家具,还有的主打金属家具。如果让我们自己去"造"一件家具会很繁琐,但通过不同的"工厂",我们只需提出需求就能拿到对应产品。这种"按需找专门工厂拿产品"的逻辑,正是C++工厂方法模式的核心思想。本文将结合家具生产场景,详解工厂方法模式的原理,并通过代码示例直观呈现其实现。

一、工厂方法模式核心概念

工厂方法模式是创建型设计模式的一种,它定义了一个用于创建对象的抽象工厂接口 ,让具体工厂子类 决定实例化哪一个产品类,同时使产品的创建过程与使用过程分离。

核心优势在于:当需要新增产品时,无需修改现有工厂代码,只需新增对应的"具体产品类"和"具体工厂类",完美符合"开放-封闭原则"(对扩展开放,对修改关闭)。

二、工厂方法模式的核心角色(对应家具场景)

  1. 抽象产品(Abstract Product):定义产品的统一接口,是所有具体产品的父类。对应场景中的"家具"------无论实木还是塑料材质,都属于家具,具备"展示材质"的统一行为。

  2. 具体产品(Concrete Product):实现抽象产品接口的具体实例。对应场景中的"实木椅子""塑料椅子""实木桌子"等具体家具。

  3. 抽象工厂(Abstract Factory):定义创建产品的统一接口,包含一个创建产品的抽象方法。对应场景中的"家具工厂"------所有工厂都具备"生产家具"的能力。

  4. 具体工厂(Concrete Factory):实现抽象工厂接口,重写创建产品的方法,返回具体产品实例。对应场景中的"实木家具工厂""塑料家具工厂"------专门生产某一类材质的家具。

三、家具生产场景的C++代码实现

我们以"椅子"为具体产品类型(若需扩展桌子,只需新增产品和工厂类),实现"实木椅子"和"塑料椅子"的生产逻辑,代码包含完整的类定义、工厂实现及测试流程。

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 1. 抽象产品:家具(所有具体家具的父类)
class Furniture {
public:
    // 纯虚函数:展示家具材质(强制子类实现)
    virtual void showMaterial() const = 0;
    // 虚析构函数:确保子类对象正确释放
    virtual ~Furniture() {}
};

// 2. 具体产品1:实木椅子(继承自家具)
class SolidWoodChair : public Furniture {
public:
    void showMaterial() const override {
        cout << "这是一把实木椅子,材质为胡桃木,坚固耐用!" << endl;
    }
};

// 3. 具体产品2:塑料椅子(继承自家具)
class PlasticChair : public Furniture {
public:
    void showMaterial() const override {
        cout << "这是一把塑料椅子,材质为PP环保塑料,轻便易清洁!" << endl;
    }
};

// 4. 抽象工厂:家具工厂(定义生产家具的接口)
class FurnitureFactory {
public:
    // 纯虚函数:创建家具(强制子类实现具体生产逻辑)
    virtual Furniture* createFurniture() const = 0;
    // 虚析构函数:确保子类工厂正确释放
    virtual ~FurnitureFactory() {}
};

// 5. 具体工厂1:实木家具工厂(专门生产实木椅子)
class SolidWoodFurnitureFactory : public FurnitureFactory {
public:
    Furniture* createFurniture() const override {
        // 实木工厂只生产实木椅子
        return new SolidWoodChair();
    }
};

// 6. 具体工厂2:塑料家具工厂(专门生产塑料椅子)
class PlasticFurnitureFactory : public FurnitureFactory {
public:
    Furniture* createFurniture() const override {
        // 塑料工厂只生产塑料椅子
        return new PlasticFurnitureFactory();
    }
};

// 测试函数:模拟用户通过工厂获取家具
void getFurniture(const FurnitureFactory& factory) {
    // 工厂创建产品,用户无需关心创建细节
    Furniture* furniture = factory.createFurniture();
    // 使用产品的统一接口
    furniture->showMaterial();
    // 释放产品资源
    delete furniture;
}

int main() {
    // 场景1:用户需要实木椅子,找实木家具工厂
    SolidWoodFurnitureFactory solidWoodFactory;
    cout << "=== 从实木家具工厂获取产品 ===" << endl;
    getFurniture(solidWoodFactory);

    // 场景2:用户需要塑料椅子,找塑料家具工厂
    PlasticFurnitureFactory plasticFactory;
    cout << "\n=== 从塑料家具工厂获取产品 ===" << endl;
    getFurniture(plasticFactory);

    return 0;
}

四、代码说明与运行结果

1. 代码结构解析

  • 抽象产品(Furniture) :定义纯虚函数showMaterial(),统一所有家具的"展示材质"行为,确保子类必须实现该方法。

  • 具体产品(SolidWoodChair、PlasticChair):继承Furniture,分别实现实木椅子和塑料椅子的材质展示逻辑,是工厂最终生产的"商品"。

  • 抽象工厂(FurnitureFactory) :定义纯虚函数createFurniture(),统一工厂的"生产家具"接口,子类需实现具体生产逻辑。

  • 具体工厂(SolidWoodFurnitureFactory、PlasticFurnitureFactory):继承FurnitureFactory,分别重写创建方法,返回对应材质的椅子对象------每个工厂只负责生产一类产品,符合"单一职责原则"。

  • 测试逻辑(getFurniture函数):接收抽象工厂对象,通过工厂创建产品并使用,用户无需知道产品是如何创建的,只需调用统一接口,实现"创建与使用分离"。

五、工厂方法模式的扩展与适用场景

1. 扩展案例:新增金属椅子

若需新增"金属椅子",无需修改现有代码,只需新增两个类:

cpp 复制代码
// 新增具体产品:金属椅子
class MetalChair : public Furniture {
public:
    void showMaterial() const override {
        cout << "这是一把金属椅子,材质为不锈钢,防锈耐腐!" << endl;
    }
};

// 新增具体工厂:金属家具工厂
class MetalFurnitureFactory : public FurnitureFactory {
public:
    Furniture* createFurniture() const override {
        return new MetalChair();
    }
};

在main函数中直接使用新工厂即可,完全符合"开放-封闭原则"。

2. 适用场景

  • 当产品有明确的"家族体系"(如家具包含椅子、桌子、柜子),且需要统一接口时;

  • 当需要避免"硬编码"创建产品(如不希望用大量if-else判断创建不同椅子),希望通过子类扩展产品时;

  • 当产品创建过程复杂,需将创建逻辑与使用逻辑分离时(如家具生产涉及材质采购、加工等流程,用户无需关心)。

六、总结

工厂方法模式通过"抽象工厂+具体工厂""抽象产品+具体产品"的四层结构,将产品的创建权交给子类工厂,既保证了产品接口的统一性,又实现了扩展的灵活性。就像生活中"不同材质家具找对应工厂生产"一样,该模式让代码的职责更清晰、维护更便捷,是C++开发中处理"多产品创建"场景的常用设计模式。

相关推荐
fish_xk7 小时前
c++中的引用和数组
开发语言·c++
有点。10 小时前
C++ ⼀级 2024 年 03 ⽉
c++
CC.GG10 小时前
【C++】二叉搜索树
java·c++·redis
Savior`L11 小时前
二分算法及常见用法
数据结构·c++·算法
深海潜水员11 小时前
OpenGL 学习笔记 第一章:绘制一个窗口
c++·笔记·学习·图形渲染·opengl
mmz120712 小时前
前缀和问题(c++)
c++·算法·图论
ULTRA??12 小时前
初学protobuf,C++应用例子(AI辅助)
c++·python
旖旎夜光13 小时前
list实现(7)(上)
c++
不会c嘎嘎13 小时前
深入理解 C++ 异常机制:从原理到工程实践
开发语言·c++