抽象工厂模式

现实世界的例子

以我们之前在简单工厂模式中提到的门为例简单工厂模式-CSDN博客。根据你的需求,你可能会从木门店获得一扇木门,从铁匠铺获得一扇铁门,或从相应的店铺获得一扇PVC门。此外,你可能需要具有不同专业技能的人来安装门,例如木匠安装木门,焊工安装铁门等。由此可见,门之间现在有了依赖关系,木门需要木匠,铁门需要焊工等。

通俗解释

一个工厂的工厂;一个将单个但相关/依赖的工厂组合在一起而不指定其具体类的工厂。

维基百科的解释

抽象工厂模式提供了一种封装一组具有共同主题的个体工厂的方法,而不指定它们的具体类。

程序示例

将上述门的例子进行编程实现。首先,我们有一个Door接口和一些实现类:

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

class Door {
public:
    virtual void getDescription() const = 0;
    virtual ~Door() = default;
};

class WoodenDoor : public Door {
public:
    void getDescription() const override {
        std::cout << "I am a wooden door" << std::endl;
    }
};

class IronDoor : public Door {
public:
    void getDescription() const override {
        std::cout << "I am an iron door" << std::endl;
    }
};

然后我们有一些针对不同门类型的安装专家:

cpp 复制代码
class DoorFittingExpert {
public:
    virtual void getDescription() const = 0;
    virtual ~DoorFittingExpert() = default;
};

class Welder : public DoorFittingExpert {
public:
    void getDescription() const override {
        std::cout << "I can only fit iron doors" << std::endl;
    }
};

class Carpenter : public DoorFittingExpert {
public:
    void getDescription() const override {
        std::cout << "I can only fit wooden doors" << std::endl;
    }
};

现在我们有一个抽象工厂,它允许我们创建一组相关对象,即木门工厂会创建一扇木门和一位木门安装专家,铁门工厂会创建一扇铁门和一位铁门安装专家:

cpp 复制代码
class DoorFactory {
public:
    virtual std::shared_ptr<Door> makeDoor() const = 0;
    virtual std::shared_ptr<DoorFittingExpert> makeFittingExpert() const = 0;
    virtual ~DoorFactory() = default;
};

class WoodenDoorFactory : public DoorFactory {
public:
    std::shared_ptr<Door> makeDoor() const override {
        return std::make_shared<WoodenDoor>();
    }
    std::shared_ptr<DoorFittingExpert> makeFittingExpert() const override {
        return std::make_shared<Carpenter>();
    }
};

class IronDoorFactory : public DoorFactory {
public:
    std::shared_ptr<Door> makeDoor() const override {
        return std::make_shared<IronDoor>();
    }
    std::shared_ptr<DoorFittingExpert> makeFittingExpert() const override {
        return std::make_shared<Welder>();
    }
};

可以这样使用:

cpp 复制代码
int main() {
    std::shared_ptr<DoorFactory> woodenFactory = std::make_shared<WoodenDoorFactory>();

    std::shared_ptr<Door> door = woodenFactory->makeDoor();
    std::shared_ptr<DoorFittingExpert> expert = woodenFactory->makeFittingExpert();

    door->getDescription();  // 输出: I am a wooden door
    expert->getDescription(); // 输出: I can only fit wooden doors

    std::shared_ptr<DoorFactory> ironFactory = std::make_shared<IronDoorFactory>();

    door = ironFactory->makeDoor();
    expert = ironFactory->makeFittingExpert();

    door->getDescription();  // 输出: I am an iron door
    expert->getDescription(); // 输出: I can only fit iron doors

    return 0;
}

如你所见,木门工厂封装了木匠和木门,铁门工厂封装了铁门和焊工。因此,它确保了我们为每扇门创建的配套专家都是正确的。

类图

类关系

  • Door 接口和实现类

Door: 定义了一个抽象方法 getDescription(), 这是所有门类都必须实现的方法。

WoodenDoor: 实现了 Door 接口的 getDescription() 方法,描述它是一个木门。

IronDoor: 实现了 Door 接口的 getDescription() 方法,描述它是一个铁门。

WoodenDoor 和 IronDoor 都实现了 Door 接口,这意味着它们必须提供 getDescription() 方法的具体实现。

  • DoorFittingExpert 接口和实现类

DoorFittingExpert: 定义了一个抽象方法 getDescription(), 这是所有门安装专家类都必须实现的方法。

Welder: 实现了 DoorFittingExpert 接口的 getDescription() 方法,描述它是一个只能安装铁门的焊工。

Carpenter: 实现了 DoorFittingExpert 接口的 getDescription() 方法,描述它是一个只能安装木门的木匠。

Welder 和 Carpenter 都实现了 DoorFittingExpert 接口,这意味着它们必须提供 getDescription() 方法的具体实现。

  • DoorFactory 接口和实现类

DoorFactory: 定义了两个抽象方法 makeDoor() 和 makeFittingExpert(), 这是所有门工厂类都必须实现的方法。

WoodenDoorFactory: 实现了 DoorFactory 接口的 makeDoor() 方法,返回一个 WoodenDoor 实例;实现 makeFittingExpert() 方法,返回一个 Carpenter 实例。

IronDoorFactory: 实现了 DoorFactory 接口的 makeDoor() 方法,返回一个 IronDoor 实例;实现 makeFittingExpert() 方法,返回一个 Welder 实例。

WoodenDoorFactory 和 IronDoorFactory 都实现了 DoorFactory 接口,这意味着它们必须实现 makeDoor() 和 makeFittingExpert() 方法。每个工厂类负责创建一组相关的对象(门和安装专家)。

何时使用?

当存在具有不那么简单的创建逻辑的相互依赖关系时,可以使用抽象工厂模式。

相关推荐
moshuying26 分钟前
块扩散 + GDN 改造:Clover 把「并行生成」塞进了 Agent 的长上下文里
前端·算法
没落之王39 分钟前
历史系统建模:宋初太祖太宗「再立天庭」秩序重构推演
人工智能·算法·重构
INGNIGHT1 小时前
91 · 最小调整代价(序列dp)
数据结构·算法·leetcode
moshuying1 小时前
扩散模型开始写代码、开网页了:350 亿参数,速度比 Jev 快一倍
前端·算法
小超人诞生日记1 小时前
C++ 异常机制详解:从抛出捕获到异常安全
c++·算法
多弗朗皮卡丘2 小时前
C++的IO流
开发语言·c++·io流·文件io流
labuladong3 小时前
机器学习&神经网络 系列教程上线
神经网络·算法·机器学习
xiangyun613 小时前
C++ 手撕 shared_ptr:引用计数与控制块到底长什么样?
开发语言·c++·算法·面试·stl
学习论之费曼学习法3 小时前
无人值守AI内容矩阵实战(8):标题 A/B 实验的 6 个工程实现细节,隔日对比与自动判胜
人工智能·python·算法·矩阵·自动化·a/b测试·内容矩阵
Carl_奕然3 小时前
【机器视觉】最强算法之:3D高斯泼溅(3D Gaussian Splatting)
人工智能·python·算法·目标检测·计算机视觉·3d