工厂方法模式与抽象工厂模式

工厂方法模式 (Factory Method)

定义: 工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。

优点

  1. 解耦:客户端代码与具体的产品类解耦,只依赖于产品的接口。
  2. 可扩展性:新增产品只需实现相应的工厂方法,无需修改现有代码。
  3. 灵活性:可以根据具体需求选择不同的产品。

应用场景

  • 当一个类不知道它所需要的对象的类时。
  • 当一个类希望通过子类来指定所创建的对象时。
  • 当类的实例化过程非常复杂时。

C++ 示例代码

以下是一个简单的工厂方法模式示例,展示了如何创建不同类型的汽车。

1. 产品接口

首先,我们定义一个汽车的接口。

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

// 产品接口
class Car {
public:
    virtual void drive() = 0; // 驾驶方法
    virtual ~Car() = default; // 虚析构函数
};
2. 具体产品

接下来,我们定义具体的汽车类,分别实现 Car 接口。

cpp 复制代码
// 具体产品:轿车
class Sedan : public Car {
public:
    void drive() override {
        std::cout << "Driving a Sedan.\n";
    }
};

// 具体产品:SUV
class SUV : public Car {
public:
    void drive() override {
        std::cout << "Driving an SUV.\n";
    }
};
3. 工厂接口

然后,我们定义一个工厂接口,用于创建汽车对象。

cpp 复制代码
// 工厂接口
class CarFactory {
public:
    virtual std::unique_ptr<Car> createCar() = 0; // 工厂方法
    virtual ~CarFactory() = default; // 虚析构函数
};
4. 具体工厂

实现具体工厂类,分别创建不同类型的汽车。

cpp 复制代码
// 具体工厂:轿车工厂
class SedanFactory : public CarFactory {
public:
    std::unique_ptr<Car> createCar() override {
        return std::make_unique<Sedan>(); // 创建轿车
    }
};

// 具体工厂:SUV工厂
class SUVFactory : public CarFactory {
public:
    std::unique_ptr<Car> createCar() override {
        return std::make_unique<SUV>(); // 创建SUV
    }
};
5. 客户端代码

最后,我们在客户端代码中使用这些工厂。

cpp 复制代码
int main() {
    // 创建轿车工厂并生产轿车
    std::unique_ptr<CarFactory> sedanFactory = std::make_unique<SedanFactory>();
    std::unique_ptr<Car> sedan = sedanFactory->createCar();
    sedan->drive(); // 输出: Driving a Sedan.

    // 创建SUV工厂并生产SUV
    std::unique_ptr<CarFactory> suvFactory = std::make_unique<SUVFactory>();
    std::unique_ptr<Car> suv = suvFactory->createCar();
    suv->drive(); // 输出: Driving an SUV.

    return 0;
}

总结

在这个示例中,工厂方法模式允许我们通过不同的工厂类创建不同类型的汽车。客户端代码只需要依赖于 CarFactoryCar 接口,而不需要了解具体的汽车实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展。

  • 抽象工厂模式

抽象工厂模式 (Abstract Factory)

定义: 抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。通过这种方式,抽象工厂模式可以使客户端代码与具体产品的实现解耦。

优点

  1. 解耦:客户端不需要依赖具体产品类,可以通过抽象接口进行交互。
  2. 可扩展性:如果需要增加新的产品,只需实现新的工厂和产品类,无需修改现有代码。
  3. 一致性:确保产品之间的兼容性和一致性。

应用场景

  • 当系统需要独立于其产品的创建、组合和表示时。
  • 当系统需要根据不同的配置来生成一系列相关的产品时。

C++ 示例代码

以下是一个简单的抽象工厂模式示例,展示了如何创建不同类型的家具(椅子和沙发)。

1. 产品接口

首先,我们定义椅子和沙发的接口。

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

// 椅子接口
class Chair {
public:
    virtual void sitOn() = 0; // 坐下的方法
    virtual ~Chair() = default; // 虚析构函数
};

// 沙发接口
class Sofa {
public:
    virtual void lieOn() = 0; // 躺下的方法
    virtual ~Sofa() = default; // 虚析构函数
};
2. 具体产品

接下来,我们定义具体的椅子和沙发类。

cpp 复制代码
// 具体产品:现代椅子
class ModernChair : public Chair {
public:
    void sitOn() override {
        std::cout << "Sitting on a Modern Chair.\n";
    }
};

// 具体产品:古典椅子
class VictorianChair : public Chair {
public:
    void sitOn() override {
        std::cout << "Sitting on a Victorian Chair.\n";
    }
};

// 具体产品:现代沙发
class ModernSofa : public Sofa {
public:
    void lieOn() override {
        std::cout << "Lying on a Modern Sofa.\n";
    }
};

// 具体产品:古典沙发
class VictorianSofa : public Sofa {
public:
    void lieOn() override {
        std::cout << "Lying on a Victorian Sofa.\n";
    }
};
3. 抽象工厂

然后,我们定义一个抽象工厂接口,用于创建椅子和沙发。

cpp 复制代码
// 抽象工厂接口
class FurnitureFactory {
public:
    virtual std::unique_ptr<Chair> createChair() = 0; // 创建椅子的方法
    virtual std::unique_ptr<Sofa> createSofa() = 0;   // 创建沙发的方法
    virtual ~FurnitureFactory() = default; // 虚析构函数
};
4. 具体工厂

实现具体工厂类,分别创建现代和古典家具。

cpp 复制代码
// 具体工厂:现代家具工厂
class ModernFurnitureFactory : public FurnitureFactory {
public:
    std::unique_ptr<Chair> createChair() override {
        return std::make_unique<ModernChair>(); // 创建现代椅子
    }
    
    std::unique_ptr<Sofa> createSofa() override {
        return std::make_unique<ModernSofa>(); // 创建现代沙发
    }
};

// 具体工厂:古典家具工厂
class VictorianFurnitureFactory : public FurnitureFactory {
public:
    std::unique_ptr<Chair> createChair() override {
        return std::make_unique<VictorianChair>(); // 创建古典椅子
    }
    
    std::unique_ptr<Sofa> createSofa() override {
        return std::make_unique<VictorianSofa>(); // 创建古典沙发
    }
};
5. 客户端代码

最后,我们在客户端代码中使用这些工厂。

cpp 复制代码
int main() {
    // 创建现代家具工厂
    std::unique_ptr<FurnitureFactory> modernFactory = std::make_unique<ModernFurnitureFactory>();
    std::unique_ptr<Chair> modernChair = modernFactory->createChair();
    std::unique_ptr<Sofa> modernSofa = modernFactory->createSofa();
    
    modernChair->sitOn(); // 输出: Sitting on a Modern Chair.
    modernSofa->lieOn();  // 输出: Lying on a Modern Sofa.

    // 创建古典家具工厂
    std::unique_ptr<FurnitureFactory> victorianFactory = std::make_unique<VictorianFurnitureFactory>();
    std::unique_ptr<Chair> victorianChair = victorianFactory->createChair();
    std::unique_ptr<Sofa> victorianSofa = victorianFactory->createSofa();

    victorianChair->sitOn(); // 输出: Sitting on a Victorian Chair.
    victorianSofa->lieOn();  // 输出: Lying on a Victorian Sofa.

    return 0;
}

总结

在这个示例中,抽象工厂模式允许我们通过不同的工厂类创建不同类型的家具(椅子和沙发)。客户端代码只依赖于 FurnitureFactory 和产品接口,而不需要了解具体的家具实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展和修改。通过这种模式,可以确保创建的家具产品之间的一致性和相互适配。

相关推荐
zxc_user10 分钟前
java后端-海外登录(谷歌/FaceBook/苹果)
java·开发语言·谷歌·facebook·海外登录
sslings17 分钟前
SpringMVC实战:动态时钟
java·学习
在未来等你40 分钟前
互联网大厂Java求职面试:AI大模型推理优化与实时数据处理架构
java·ai·大模型·向量数据库·rag·分布式系统
买了一束花44 分钟前
预分配矩阵内存提升文件数据读取速度
java·人工智能·算法·matlab
zizisuo1 小时前
Java集合框架深度剖析:结构、并发与设计模式全解析
java·javascript·数据结构·设计模式
要加油哦~1 小时前
刷题 | 牛客 - js中等题-下(更ing)30/54知识点&解答
java·开发语言·javascript
程序员鱼皮1 小时前
炸裂!Spring AI 1.0 正式发布,让 Java 再次伟大!
java·计算机·ai·程序员·互联网·开发
俺不是西瓜太郎´•ﻌ•`2 小时前
欧拉降幂(JAVA)蓝桥杯乘积幂次
java·开发语言·蓝桥杯
神码小Z2 小时前
Spring Cloud Gateway 微服务网关实战指南
java·spring boot·spring cloud
EQ-雪梨蛋花汤2 小时前
【如何做好一份技术文档?】用Javadoc与PlantUML构建高质量技术文档(API文档自动化部署)
java·api·ci·plantuml·doc