C++ 设计模式之抽象工厂模式

本文介绍了抽象工厂模式在软件设计中的应用,通过C++代码展示了如何创建一个多产品类型的系统,使用抽象工厂来管理不同风格的家具生产。它强调了抽象产品接口、具体产品类、抽象工厂接口和具体工厂类的角色以及如何在客户端透明地处理不同风格的家具订单。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【声明】本编码题目来源于【题目页面 (kamacoder.com)


【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】

【简介】什么是抽象工厂模式

        抽象⼯⼚模式也是⼀种创建型设计模式,提供了⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
        在⼯⼚⽅法模式中,每个具体⼯⼚只负责创建单⼀的产品。但是如果有多类产品呢,⽐如说“⼿机”,⼀个品牌的⼿机有⾼端机、中低端机之分,这些具体的产品都需要建⽴⼀个单独的⼯⼚类,但是它们都是相互关联的,都共同属于同⼀个品牌,这就可以使⽤到【抽象⼯⼚模式】。

        抽象⼯⼚模式可以确保⼀系列相关的产品被⼀起创建,这些产品能够相互配合使⽤,再举个例⼦,有⼀些家具,⽐如沙发、茶⼏、椅⼦,都具有古典⻛格的和现代⻛格的,抽象⼯⼚模式可以将⽣产现代⻛格的家具放在⼀个⼯⼚类中,将⽣产古典⻛格的家具放在另⼀个⼯⼚类中,这样每个⼯⼚类就可以⽣产⼀系列的家具。


【基本结构】

        抽象⼯⼚模式包含多个抽象产品接⼝,多个具体产品类,⼀个抽象⼯⼚接⼝和多个具体⼯⼚,每个具体⼯⼚负责创建⼀组相关的产品。

  • 抽象产品接⼝AbstractProduct : 定义产品的接⼝,可以定义多个抽象产品接⼝,⽐如说沙发、椅⼦、茶⼏都是抽象产品。
  • 具体产品类ConcreteProduct : 实现抽象产品接⼝,产品的具体实现,古典⻛格和沙发和现代⻛格的沙发都是具体产品。
  • 抽象⼯⼚接⼝AbstractFactory : 声明⼀组⽤于创建产品的⽅法,每个⽅法对应⼀个产品。
  • 具体⼯⼚类ConcreteFactory : 实现抽象⼯⼚接⼝,负责创建⼀组具体产品的对象,在本例中,⽣产古典⻛格的⼯⼚和⽣产现代⻛格的⼯⼚都是具体实例。

        在上⾯的图示中:

        AbstractProductA/B/C 就是抽象产品,

        ConcreteProductA2/A2/B1/B2/C1/C2 就是抽象产品的实现,

        AbstractFactory 定义了抽象⼯⼚接⼝,接⼝⾥的⽅法⽤于创建具体的产品,ConcreteFactory就是具体⼯⼚类,可以创建⼀组相关的产品。


【实现步骤】

  • 定义抽象产品接⼝(可以有多个),接⼝中声明产品的公共⽅法。
  • 实现具体产品类,在类中实现抽象产品接⼝中的⽅法。
  • 定义抽象⼯⼚接⼝,声明⼀组⽤于创建产品的⽅法。
  • 实现具体⼯⼚类,分别实现抽象⼯⼚接⼝中的⽅法,每个⽅法负责创建⼀组相关的产品。
  • 在客户端中使⽤抽象⼯⼚和抽象产品,⽽不直接使⽤具体产品的类名。

【C++编码实例】

1.题目描述

        小明家新开了两个工厂用来生产家具,一个生产现代风格的沙发和椅子,一个生产古典风格的沙发和椅子,现在工厂收到了一笔订单,请你帮他设计一个系统,描述订单需要生产家具的信息。

2.输入描述

        输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示订单的数量。 接下来的 N 行,每行输入一个字符串,字符串表示家具的类型。家具类型分为 "modern" 和 "classical" 两种。

3.输出描述

        对于每笔订单,输出字符串表示该订单需要生产家具的信息。 

modern订单会输出下面两行字符串 :

        modern chair 

        modern sofa

classical订单会输出下面两行字符串 :

        classical chair 

        classical soft

4.编码实现

#include <iostream>
#include <vector>
#include <string>

using namespace std;
// 前置声明
class Sofa;
class Chair;
class Classic;
class ModernSofa;
class ModernChair;
class ClassicSofa;
class ClassicChair;

// 定义抽象产品

// 现代风格类
class Sofa{
public:
    // 声明虚函数时一定要加上空实现  或者声明为纯虚函数
    virtual void PrintSofa() = 0;
};

// 古典风格类
class Chair{
public:    
    // 声明虚函数时一定要加上空实现  或者声明为纯虚函数
    virtual void PrintChair() = 0;
};

// 实现具体产品类

// 现代风格的沙发
class ModernSofa : public Sofa
{
public:    
    void PrintSofa() override
    {
        std::cout << "modern sofa" << endl;
    }
};

// 现代风格的椅子
class ModernChair : public Chair
{
public:    
    void PrintChair() override
    {
        std::cout << "modern chair" << endl;
    }
};

// 古典风格的沙发
class ClassicSofa : public Sofa
{
public:    
    void PrintSofa() override
    {
        std::cout << "classical sofa" << endl;
    }
};


// 古典风格的椅子
class ClassicChair : public Chair
{
public:    
    void PrintChair() override
    {
        std::cout << "classical chair" << endl;
    }
};


// 定义抽象工厂接口 -- 实例化 抽象的产品(风格)
class ProductFactory{
public:    
    // 后续需要重写
    // 声明虚函数时一定要加上空实现  或者声明为纯虚函数
    virtual Sofa* CreateSofa() = 0;
    virtual Chair* CreateChair() = 0;
};


// 实现具体工厂类(以产品的特性分类 而不是具体的产品)

// 现代工厂
class ModernProductFactory : public ProductFactory
{
public: 
    // 生产现代风的沙发
    Sofa* CreateSofa() override
    {
        return (new ModernSofa());
    }
    
    // 生产现代风的椅子
    Chair* CreateChair() override
    {
        return (new ModernChair());
    }
    
};

// 古典工厂
class ClassicProductFactory : public ProductFactory
{
public:    
    // 生产古典风的沙发
    Sofa* CreateSofa() override
    {
        return (new ClassicSofa());
    }
    
    // 生产古典风的椅子
    Chair* CreateChair() override
    {
        return (new ClassicChair());
    }
};

// 工厂产品 管理类

int main()
{
    // 产品工厂的抽象基类  用于后续不同派生类的创建
    ProductFactory *factoryPointer = nullptr;
    
    // 订单数量
    int orderNum = 0;
    // 输入的家具类型
    string furnitureType = "";
    // 已有家具类型
    string modern = "modern";
    string classical = "classical";
    // 输入订单数量
    std::cin >>  orderNum;
    
    for(int i = 0; i < orderNum; i++)
    {
        std::cin >> furnitureType;
        if(furnitureType == modern)
        {
            // 创建 现代 工厂
            factoryPointer = new ModernProductFactory();
            // 创建具体化的 椅子和沙发 对象 同时使用dynamic_cast完成向下类型转换
            ModernSofa *sofa = dynamic_cast<ModernSofa *>(factoryPointer->CreateSofa());
            ModernChair *chair = dynamic_cast<ModernChair *>(factoryPointer->CreateChair());
            // 执行相应操作
            chair->PrintChair();
            sofa->PrintSofa();
            
            // 用完记得析构掉
            delete chair;
            chair = nullptr;
            delete sofa;
            sofa = nullptr;
        }
        else if(furnitureType == classical)
        {
            // 创建古典工厂
            factoryPointer = new ClassicProductFactory();
            // 创建具体化的 椅子和沙发 对象
            ClassicSofa *sofa = dynamic_cast<ClassicSofa *>(factoryPointer->CreateSofa());
            ClassicChair *chair = dynamic_cast<ClassicChair *>(factoryPointer->CreateChair());
            // 执行相应操作
            chair->PrintChair();
            sofa->PrintSofa();
            
            // 用完记得析构掉
            delete chair;
            chair = nullptr;
            delete sofa;
            sofa = nullptr;
        }
        else continue;
        
        // 用完记得析构掉
        delete factoryPointer;
        factoryPointer = nullptr;
    }
    return 0;
}

......

To be continued.


【补充】简单⼯⼚、⼯⼚⽅法、抽象⼯⼚的区别

  • 简单⼯⼚模式:⼀个⼯⼚⽅法创建所有具体产品
  • ⼯⼚⽅法模式:⼀个⼯⼚⽅法创建⼀个具体产品
  • 抽象⼯⼚模式:⼀个⼯⼚⽅法可以创建⼀类具体产品
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码的小恐龙er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值