C++11:工厂方法模式

C++11实现工厂方法模式的问题。之前用户问过简单工厂模式,现在进阶到工厂方法模式,说明他们对设计模式的学习在逐步深入。首先,我需要回顾工厂方法模式和简单工厂模式的区别,确保自己理解正确。

工厂方法模式属于创建型模式,它定义了一个创建对象的接口,但让子类决定实例化哪一个类。也就是说,工厂方法让类的实例化延迟到子类。而简单工厂模式则是在一个工厂类里通过条件判断来决定创建哪种产品,当新增产品时需要修改工厂类的代码,这违反了开闭原则。而工厂方法模式通过引入抽象工厂和具体工厂,每个具体工厂负责创建对应的产品,这样新增产品时只需添加新的工厂和产品类,不需要修改已有代码,符合开闭原则。

接下来,我需要考虑如何用C++11的特性来实现这个模式。用户之前的例子中用到了override、unique_ptr、auto等特性,这次应该保持一致性。需要确保代码中正确使用这些特性,比如虚函数的override关键字,智能指针管理资源,避免内存泄漏。

然后,我需要设计类结构。抽象产品类Shape,具体产品类Circle和Rectangle,对应的抽象工厂类ShapeFactory,具体工厂类CircleFactory和RectangleFactory。每个具体工厂负责创建对应的产品对象。这样客户端通过调用具体工厂的createShape方法来获得产品实例。

另外,用户可能希望看到工厂方法模式与简单工厂模式的区别,所以应该在示例中体现这一点。比如,在简单工厂中,所有产品由一个工厂类创建,而工厂方法模式中每个产品有自己的工厂类,这样扩展性更好。

还要注意代码的可读性和注释,方便用户理解每个部分的作用。例如,使用C++11的nullptr代替NULL,使用unique_ptr自动管理内存,确保资源安全释放。

然后,编写代码示例。抽象工厂类定义一个纯虚函数createShape,返回unique_ptr<Shape>。每个具体工厂继承并实现这个函数,返回对应的具体产品。客户端使用时,实例化具体的工厂对象,然后调用createShape方法得到产品对象。

测试部分,需要展示不同工厂创建不同产品,并调用它们的draw方法。同时,可以展示如何扩展新的产品和工厂,比如新增Triangle和TriangleFactory,说明扩展时不需要修改现有代码,只需添加新类,符合开闭原则。

最后,总结工厂方法模式的优势,比如解耦、符合开闭原则、扩展性好等,并指出可能的缺点,如类数量增加,系统复杂度提高。这样用户能全面了解该模式的适用场景和注意事项。

在思考过程中,我需要确保没有遗漏C++11的特性应用,比如是否还有其他的特性可以应用,比如基于范围的for循环或者移动语义等,但在这个例子中,可能主要用到的还是override、unique_ptr、auto和nullptr。同时,要注意代码的规范,比如虚析构函数的声明,避免潜在的内存泄漏问题。

可能用户会混淆工厂方法模式和抽象工厂模式,所以在说明时需要明确两者的区别。工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对多个产品等级结构,但这里用户的问题是工厂方法,所以不需要展开讨论抽象工厂。

确认代码示例的正确性,比如具体工厂类中的createShape方法是否正确地返回了对应的产品实例,是否使用了智能指针,以及客户端代码是否正确调用了工厂方法。此外,确保所有产品类正确继承自抽象产品类,并实现了虚函数。

总结来说,我需要提供一个结构清晰、符合C++11标准、展示工厂方法模式核心思想的代码示例,并附上详细的解释,帮助用户理解其实现和优势。

以下是使用 C++11 实现的工厂方法模式示例,相比简单工厂模式更符合开闭原则(OCP):

cpp

复制

复制代码
#include <iostream>
#include <memory>
#include <string>

// 抽象产品类
class Shape {
public:
    virtual void draw() = 0;
    virtual ~Shape() = default;
};

// 具体产品类:圆形
class Circle : public Shape {
public:
    void draw() override {
        std::cout << "绘制圆形 ◯" << std::endl;
    }
};

// 具体产品类:矩形
class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "绘制矩形 ▭" << std::endl;
    }
};

// 新增具体产品类:三角形
class Triangle : public Shape {
public:
    void draw() override {
        std::cout << "绘制三角形 △" << std::endl;
    }
};

// 抽象工厂类
class ShapeFactory {
public:
    virtual std::unique_ptr<Shape> createShape() = 0;
    virtual ~ShapeFactory() = default;
};

// 具体工厂类:圆形工厂
class CircleFactory : public ShapeFactory {
public:
    std::unique_ptr<Shape> createShape() override {
        return std::make_unique<Circle>();  // C++14 特性,可用 new Circle() 替代
    }
};

// 具体工厂类:矩形工厂
class RectangleFactory : public ShapeFactory {
public:
    std::unique_ptr<Shape> createShape() override {
        return std::make_unique<Rectangle>();
    }
};

// 新增具体工厂类:三角形工厂
class TriangleFactory : public ShapeFactory {
public:
    std::unique_ptr<Shape> createShape() override {
        return std::make_unique<Triangle>();
    }
};

int main() {
    // 创建工厂对象
    auto circleFactory = std::make_unique<CircleFactory>();
    auto rectFactory = std::make_unique<RectangleFactory>();
    auto triFactory = std::make_unique<TriangleFactory>();

    // 使用工厂创建产品
    auto circle = circleFactory->createShape();
    auto rectangle = rectFactory->createShape();
    auto triangle = triFactory->createShape();

    // 使用产品
    circle->draw();    // 输出:绘制圆形 ◯
    rectangle->draw(); // 输出:绘制矩形 ▭
    triangle->draw();  // 输出:绘制三角形 △

    return 0;
}

代码特点(使用 C++11/14 特性):

  1. 模式实现特点

    • 每个具体产品对应一个具体工厂类

    • 新增产品类型时只需添加新工厂类,无需修改已有代码

    • 使用 std::unique_ptr 进行自动内存管理

    • 通过 override 关键字显式声明重写

  2. 类结构说明

    ascii

    复制

    复制代码
    ┌───────────────┐       ┌───────────────┐
    │  ShapeFactory │<>---->│    Shape      │
    └───────────────┘       └───────────────┘
           △                      △
           │                      │
    ┌──────┴───────┐      ┌───────┴───────┐
    │ CircleFactory│      │    Circle     │
    ├──────────────┤      ├───────────────┤
    │RectangleFactory│    │   Rectangle   │
    ├──────────────┤      ├───────────────┤
    │ TriangleFactory│    │   Triangle    │
    └───────────────┘      └──────────────┘
  3. C++11 关键特性应用

    • override 关键字:明确虚函数重写

    • unique_ptr:自动内存管理

    • 默认虚析构函数:确保正确的对象销毁

    • 类型推导(auto):简化代码书写

  4. 模式优势

    • 更好的扩展性:新增产品类型时只需添加新工厂类

    • 符合开闭原则:无需修改现有工厂代码

    • 解耦更彻底:客户端仅依赖抽象接口

    • 多态性支持:可以运行时动态选择工厂

  5. 与简单工厂对比

    特性 简单工厂模式 工厂方法模式
    工厂类数量 1个 N个(每个产品对应一个)
    扩展性 需要修改工厂类 只需添加新工厂类
    复杂度 简单 较高
    符合开闭原则
    适用场景 产品类型较少且固定 需要灵活扩展的产品体系

扩展示例(新增产品类型):

cpp

复制

复制代码
// 新增产品:五边形
class Pentagon : public Shape {
public:
    void draw() override {
        std::cout << "绘制五边形 ⬠" << std::endl;
    }
};

// 对应的新工厂
class PentagonFactory : public ShapeFactory {
public:
    std::unique_ptr<Shape> createShape() override {
        return std::make_unique<Pentagon>();
    }
};

// 客户端使用
int main() {
    auto pentagonFactory = std::make_unique<PentagonFactory>();
    auto pentagon = pentagonFactory->createShape();
    pentagon->draw();  // 输出:绘制五边形 ⬠
    return 0;
}
相关推荐
计算机-秋大田2 小时前
基于Spring Boot的乡村养老服务管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
盖盖衍上2 小时前
Java 泛型(Generics)详解与使用
java·开发语言·windows
没有十八岁3 小时前
云创智城YunCharge 新能源二轮、四轮充电解决方案(云快充、万马爱充、中电联、OCPP1.6J等多个私有单车、汽车充电协议)之新能源充电行业系统说明书
java·数据库·spring·汽车
小萌新上大分3 小时前
Minio搭建并在SpringBoot中使用完成用户头像的上传
java·spring boot·后端·minio·minio搭建·头像上传·minio入门
B站计算机毕业设计超人4 小时前
计算机毕业设计SpringBoot+Vue.js校园失物招领系统(源码+文档+PPT+讲解)
java·vue.js·spring boot·后端·毕业设计·课程设计·毕设
计算机-秋大田4 小时前
基于SpringBoot的环保网站的设计与实现(源码+SQL脚本+LW+部署讲解等)
java·vue.js·spring boot·后端·课程设计
汤姆yu4 小时前
基于springboot的高校物品捐赠系统
java·spring boot·后端·高校物品捐赠
magic 2454 小时前
深入理解Java网络编程:从基础到高级应用
java·开发语言
岁岁岁平安4 小时前
spring注解开发(Spring整合JUnit+MyBatis)(7)
java·spring·junit·log4j·mybatis
萌の鱼4 小时前
leetcode 48. 旋转图像
数据结构·c++·算法·leetcode