当前位置: 首页 > news >正文

【设计模式】工厂模式

首先了解一下什么是工厂方法模式?

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种方法来封装对象的创建逻辑。具体来说,它通过定义一个创建对象的接口(即工厂方法),但将具体的对象实例化工作推迟到子类中完成。这样,客户端代码可以在不知道具体类的情况下创建对象,从而实现创建与使用的分离。


作用

工厂方法模式在软件设计中有以下几个主要作用:

  1. 解耦
    将对象的创建与使用分离,客户端无需了解具体类的实现细节,只需通过工厂方法获取对象即可。这降低了代码的耦合度。

  2. 扩展性
    当需要添加新的对象类型时,只需增加新的具体工厂类和产品类,而无需修改现有代码,符合之前我们提到的“开闭原则”(对扩展开放,对修改关闭)(SOLID的O)。

  3. 灵活性
    通过工厂方法,系统可以在运行时动态决定实例化哪个类,增加了程序的灵活性。


用法

工厂方法模式适用于以下场景:

  • 当一个类无法预先知道需要创建的具体对象类型时。
  • 当希望由子类决定创建哪种对象时。
  • 当需要将对象的创建职责委托给多个子类中的某一个时。

C++ 示例

下面通过一个完整的 C++ 示例来说明工厂方法模式。我们以创建不同类型车辆(汽车和卡车)为例。
具体的UML图如下:

工厂方法示例UML图

1. 定义产品接口

首先,定义一个抽象基类 Vehicle,它声明了所有车辆必须实现的方法。

#include <iostream>

class Vehicle {
public:
    virtual void drive() const = 0;  // 纯虚函数,所有子类必须实现
    virtual ~Vehicle() = default;    // 虚析构函数,确保正确释放资源
};
2. 实现具体产品类

接下来,创建两个具体产品类 CarTruck,它们继承自 Vehicle,并实现 drive 方法。

class Car : public Vehicle {
public:
    void drive() const override {
        std::cout << "Driving a car." << std::endl;
    }
};

class Truck : public Vehicle {
public:
    void drive() const override {
        std::cout << "Driving a truck." << std::endl;
    }
};
3. 定义工厂接口

然后,定义一个抽象工厂类 VehicleFactory,它包含一个纯虚函数 createVehicle,用于创建 Vehicle 对象的实例。

class VehicleFactory {
public:
    virtual Vehicle* createVehicle() const = 0;  // 工厂方法,子类必须实现
    virtual ~VehicleFactory() = default;         // 虚析构函数
};
4. 实现具体工厂类

再创建两个具体工厂类 CarFactoryTruckFactory,它们继承自 VehicleFactory,并实现 createVehicle 方法,分别返回 CarTruck 实例。

class CarFactory : public VehicleFactory {
public:
    Vehicle* createVehicle() const override {
        return new Car();
    }
};

class TruckFactory : public VehicleFactory {
public:
    Vehicle* createVehicle() const override {
        return new Truck();
    }
};
5. 使用工厂方法

在客户端代码中,通过工厂对象创建车辆实例,而无需直接实例化具体类。

int main() {
    // 创建汽车工厂并生产汽车
    VehicleFactory* carFactory = new CarFactory();  //注意这里含有纯虚函数的抽象类,是不可以初始化的,但是它的指针可以接受子类new出来的对象
    Vehicle* car = carFactory->createVehicle();
    car->drive();  // 输出: Driving a car.
    delete car;    // 释放车辆对象
    delete carFactory;  // 释放工厂对象

    // 创建卡车工厂并生产卡车
    VehicleFactory* truckFactory = new TruckFactory();
    Vehicle* truck = truckFactory->createVehicle();
    truck->drive();  // 输出: Driving a truck.
    delete truck;    // 释放车辆对象
    delete truckFactory;  // 释放工厂对象

    return 0;
}

运行以上代码,输出如下:

Driving a car.
Driving a truck.

详细解释

让我们逐步分析这个示例的每个组成部分:

  1. 产品接口(Vehicle)

    • Vehicle 是一个抽象基类,定义了所有具体产品(CarTruck)必须实现的接口(drive 方法)。
    • 使用纯虚函数(= 0)确保子类必须提供实现。
    • 虚析构函数确保通过基类指针删除对象时能正确释放资源。
  2. 具体产品(Car、Truck)

    • CarTruck 是具体的产品类,继承自 Vehicle,并实现了 drive 方法。
    • 它们代表系统中实际的对象类型,提供了具体的功能实现。
  3. 工厂接口(VehicleFactory)

    • VehicleFactory 是一个抽象工厂类,定义了工厂方法 createVehicle
    • 该方法是纯虚的,意味着具体工厂类必须实现它来创建具体产品。
  4. 具体工厂(CarFactory、TruckFactory)

    • CarFactoryTruckFactory 是具体工厂类,分别负责创建 CarTruck 对象。
    • 通过重写 createVehicle,它们封装了对象的创建逻辑。
  5. 客户端代码

    • 客户端通过 VehicleFactory 接口调用 createVehicle 方法来创建对象。
    • 客户端无需知道具体的产品类(CarTruck)或其实现细节,只需与工厂交互即可。
    • 这种方式实现了创建与使用的解耦。

模式优势

  • 解耦:客户端代码不直接依赖具体产品类(CarTruck),而是通过工厂接口操作。
  • 扩展性:如果需要添加新的车辆类型(如 Motorcycle),只需新增 Motorcycle 类和对应的 MotorcycleFactory 类,无需修改现有代码。
  • 灵活性:可以在运行时根据需要选择不同的工厂,动态创建不同类型的对象。

总结

工厂方法模式通过将对象的创建逻辑封装在子类中,实现了对象创建与使用的分离。它在 C++ 中通过抽象工厂类和具体工厂类的配合,提供了灵活、可扩展的创建机制。在上述示例中,我们通过创建车辆的工厂方法模式展示了其核心思想:定义接口,推迟实现,解耦使用。这种模式特别适合需要动态创建多种对象类型的场景,是设计模式中非常实用的一种方法。

相关文章:

  • 信息学奥赛一本通 1514:【例 2】最大半连通子图 | 洛谷 P2272 [ZJOI2007] 最大半连通子图
  • vue watch数据监听
  • R语言——字符串
  • RTSP/Onvif安防监控平台EasyNVR抓包命令tcpdump使用不了,该如何解决?
  • 模型搭建与复现
  • 【Linux网络-多路转接select】
  • Active Directory (AD): 企业网络用户管理的重要性及 AD 迁移方法
  • UNIX网络编程笔记:TCP、UDP、SCTP编程的区别
  • 解决 MySQL 的 sql_mode 中包含 only_full_group_by模式导致group by SQL报错
  • PHP eval 长度限制绕过与 Webshell 获取
  • 穿透Session 0隔离
  • 【每日算法】Day 6-1:哈希表从入门到实战——高频算法题(C++实现)
  • 网络安全基础:五类安全服务、八种安全机制与OSI七层模型的全面解析
  • HTML——什么是块级元素,什么是内联元素,有何区别
  • 使用Django创建项目及介绍
  • OBS虚拟背景深度解析:无需绿幕也能打造专业教学视频(附插件对比)
  • 小蓝的括号串(栈,dfs)
  • 电气、电子信息与通信工程的探索与应用
  • Python正则表达式(一)
  • 远程登录服务(ssh)
  • 沈丘做网站去哪里/提供seo顾问服务适合的对象是
  • 网站开发怎么拉客户/如何优化百度seo排名
  • 有经验的邵阳网站建设/推广码怎么填
  • 免费手机app制作软件/简述seo的应用范围
  • 网站建设遇到哪些问题/广西网络优化seo
  • 内容网站 如何做采集/培训心得体会