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

工厂方法模式 (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 和产品接口,而不需要了解具体的家具实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展和修改。通过这种模式,可以确保创建的家具产品之间的一致性和相互适配。

相关推荐
考虑考虑3 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261353 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊5 小时前
Java学习第22天 - 云原生与容器化
java
渣哥6 小时前
原来 Java 里线程安全集合有这么多种
java
间彧6 小时前
Spring Boot集成Spring Security完整指南
java
间彧7 小时前
Spring Secutiy基本原理及工作流程
java
Java水解8 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆10 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学10 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole10 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端