设计模式之工厂模式(C++)

简介: 设计模式之工厂模式(C++)

一、工厂模式是什么?

      工厂模式是一种创建型的软件设计模式。定义一个用于创建对象的工厂接口,并让工厂子类决定实例化哪一个产品类,使产品类的实例化延迟到工厂子类中执行。说白了就是用来造东西的,一般是比较简单的东西,我们不需要知道它如何生产的,直接从工厂拿到产品即可。


      工厂模式的优点:

  1. 良好的封装性。将产品的实例化封装执行,避免被修改,这样的产品具备良好的一致性。
  2. 良好的扩展性。增加产品时,同步增加一个工厂子类,不会违反开闭原则。
  3. 标准的解耦合框架。使用者只需要知道自己要什么产品即可,不用去管产品具体的特性等等,降低了模块间的耦合。

     工厂模式的缺点:

  1. 代码量大。每加一个产品,都要加一个工厂子类,代码会显得臃肿。
  2. 不利于扩展复杂的产品结构。如果你要苹果、香蕉、梨,工厂模式的结构还可以,但如果你要山东的苹果、海南的香蕉、北京的苹果,就显得结构呆呆的。这可以用抽象工厂模式解决,对产品族和产品种类进行区分。

二、简单工厂模式

      在介绍工厂模式前,先介绍其前身-简单工厂模式,简单工厂模式是用一个简单的工厂类,直接对产品进行实例化,虽然大大减少了代码量,但是违反了设计中的开闭原则,因为每次添加产品,工厂类都要进行修改。

2.1 结构图

      客户端即Main主函数,调用简单工厂制造产品,并获取产品。具体要什么产品由客户端命令决定。

2.2 代码示例

      场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。

//Prodect.h
/****************************************************/
#pragma once
#include <iostream>
using namespace std;
// 产品种类
enum PRODECT_TYPE
{
  APPLE,                     // 苹果
  BANANA,            // 香蕉
  PEAR             // 梨
};
// 抽象产品类
class Prodect
{
public:
  // 构造函数
  Prodect(int price) :m_price(price) {};
  // 析构函数
  virtual ~Prodect() {};
  // 获取价格
  int getPrice() {
    return m_price;
  }
protected:
  // 产品价格
  int m_price;
};
// 具体产品类-苹果
class AppleProdect : public Prodect
{
public:
  // 构造函数
  AppleProdect(int price) :Prodect(price) {
    cout << "获得了一个苹果。" << endl;
  };
  // 析构函数
  virtual ~AppleProdect() {
    cout << "吃掉了一个苹果。" << endl;
  };
};
// 具体产品类-香蕉
class BananaProdect : public Prodect
{
public:
  // 构造函数
  BananaProdect(int price) :Prodect(price) {
    cout << "获得了一个香蕉。" << endl;
  };
  // 析构函数
  virtual ~BananaProdect() {
    cout << "吃掉了一个香蕉。" << endl;
  };
};
// 具体产品类-梨
class PearProdect : public Prodect
{
public:
  // 构造函数
  PearProdect(int price) :Prodect(price) {
    cout << "获得了一个梨。" << endl;
  };
  // 析构函数
  virtual ~PearProdect() {
    cout << "吃掉了一个梨。" << endl;
  };
};
//Factory.h
/****************************************************/
#pragma once
#include <iostream>
#include "Prodect.h"
using namespace std;
// 简单工厂
class SimpleFactory
{
public:
  // 获取产品
  Prodect* getProdect(PRODECT_TYPE type) {
    Prodect* prodect = nullptr;
    switch (type)
    {
    case APPLE:
      prodect = new AppleProdect(5);
      break;
    case BANANA:
      prodect = new BananaProdect(2);
      break;
    case PEAR:
      prodect = new PearProdect(3);
      break;
    default:
      cout << "无该产品。" << endl;
      break;
    }
    return prodect;
  }
};
//main.cpp
/****************************************************/
#include <iostream>
#include "Factory.h"
#include "Prodect.h"
using namespace std;
int main()
{
  SimpleFactory* factory = new SimpleFactory();
  cout << "开始生产。" << endl;
  Prodect *A = factory->getProdect(APPLE);
  Prodect *B = factory->getProdect(BANANA);
  Prodect *C = factory->getProdect(PEAR);
  int applePrice = A->getPrice();
  int bananaPrice = B->getPrice();
  int pearPrice = C->getPrice();
  int sum = A->getPrice() + B->getPrice() + C->getPrice();
  cout << "苹果价格:" << applePrice << "元。" << endl;
  cout << "香蕉价格:" << bananaPrice << "元。" << endl;
  cout << "梨子价格:" << pearPrice << "元。" << endl;
  cout << "累计消费:" << sum << "元。" << endl;
  delete A;
  delete B;
  delete C;
    delete factory;
  cout << "享用完毕。" << endl;
  return 0;
}

    程序结果如下。

       在上述示例中,我们可以看到,如果我想给工厂再添加一个产品,那么除了添加一个产品子类外,还要跑到简单工厂的类中进行switch的扩展,这样不利于代码的封装,破坏了开闭原则。而工厂模式的设计能弥补该不足。

三、工厂模式

3.1 结构图

      客户端即Main主函数,通过工厂子类来制造对应的产品,并获取产品。具体要什么产品由工厂子类决定。

3.2 代码示例

      场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。

//Prodect.h
/****************************************************/
#pragma once
#include <iostream>
using namespace std;
// 抽象产品类
class Prodect
{
public:
  // 构造函数
  Prodect(int price) :m_price(price) {};
  // 析构函数
  virtual ~Prodect() {};
  // 获取价格
  int getPrice() {
    return m_price;
  }
protected:
  // 产品价格
  int m_price;
};
// 具体产品类-苹果
class AppleProdect : public Prodect
{
public:
  // 构造函数
  AppleProdect(int price) :Prodect(price) {
    cout << "获得了一个苹果。" << endl;
  };
  // 析构函数
  virtual ~AppleProdect() {
    cout << "吃掉了一个苹果。" << endl;
  };
};
// 具体产品类-香蕉
class BananaProdect : public Prodect
{
public:
  // 构造函数
  BananaProdect(int price) :Prodect(price) {
    cout << "获得了一个香蕉。" << endl;
  };
  // 析构函数
  virtual ~BananaProdect() {
    cout << "吃掉了一个香蕉。" << endl;
  };
};
// 具体产品类-梨
class PearProdect : public Prodect
{
public:
  // 构造函数
  PearProdect(int price) :Prodect(price) {
    cout << "获得了一个梨。" << endl;
  };
  // 析构函数
  virtual ~PearProdect() {
    cout << "吃掉了一个梨。" << endl;
  };
};
//Factory.h
/****************************************************/
#pragma once
#include <iostream>
#include "Prodect.h"
using namespace std;
// 抽象工厂类
class Factory
{
public:
  // 获取产品
  virtual Prodect* getProdect() = 0;
};
// 具体工厂类-苹果
class AppleFactory : public Factory
{
public:
  // 获取产品
  virtual Prodect* getProdect() {
    Prodect* prodect = new AppleProdect(5);
    return prodect;
  }
};
// 具体工厂类-香蕉
class BananaFactory : public Factory
{
public:
  // 获取产品
  virtual Prodect* getProdect() {
    Prodect* prodect = new BananaProdect(2);
    return prodect;
  }
};
// 具体工厂类-梨
class PearFactory : public Factory
{
public:
  // 获取产品
  virtual Prodect* getProdect() {
    Prodect* prodect = new PearProdect(3);
    return prodect;
  }
};
//main.cpp
/****************************************************/
#include <iostream>
#include "Factory.h"
#include "Prodect.h"
using namespace std;
int main()
{
  Factory* factoryA = new AppleFactory();
  Factory* factoryB = new BananaFactory();
  Factory* factoryC = new PearFactory();
  cout << "开始生产。" << endl;
  Prodect *A = factoryA->getProdect();
  Prodect *B = factoryB->getProdect();
  Prodect *C = factoryC->getProdect();
  int applePrice = A->getPrice();
  int bananaPrice = B->getPrice();
  int pearPrice = C->getPrice();
  int sum = A->getPrice() + B->getPrice() + C->getPrice();
  cout << "苹果价格:" << applePrice << "元。" << endl;
  cout << "香蕉价格:" << bananaPrice << "元。" << endl;
  cout << "梨子价格:" << pearPrice << "元。" << endl;
  cout << "累计消费:" << sum << "元。" << endl;
  delete A;
  delete B;
  delete C;
    delete factoryA;
    delete factoryB;
    delete factoryC;
  cout << "享用完毕。" << endl;
  return 0;
}

      程序结果如下。

       这样设计的好处就是如果多一个产品,那就只需要在产品类和工厂类中各扩展一个子类即可,不影响原有的程序。

四、总结

      我尽可能用较通俗的话语和直观的代码例程,来表述我对工厂模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解工厂模式。

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
5月前
|
设计模式 C++
C++一分钟之-设计模式:工厂模式与抽象工厂
【7月更文挑战第14天】设计模式是解决软件设计问题的通用方案。工厂模式与抽象工厂模式是创建型模式,用于对象创建而不暴露创建逻辑。工厂模式推迟实例化到子类,但过度使用会增加复杂性。抽象工厂则创建相关对象族,但过度抽象可能造成不必要的复杂度。两者均应按需使用,确保设计灵活性。代码示例展示了C++中如何实现这两种模式。
47 3
|
5月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
65 2
|
7月前
|
设计模式 开发框架 算法
C++中的设计模式:基本概念与应用
C++中的设计模式:基本概念与应用
72 2
|
7月前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
222 1
|
7月前
|
设计模式 算法 C++
从 C++ 优化状态机实现:结合设计模式的实用指南
从 C++ 优化状态机实现:结合设计模式的实用指南
567 1
|
7月前
|
设计模式 关系型数据库 数据库
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
76 1
|
7月前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
7月前
|
设计模式 机器学习/深度学习 算法
C++设计模式新篇章:掌握状态委托
C++设计模式新篇章:掌握状态委托
124 0
|
7月前
|
设计模式 存储 安全
C++多线程管理的艺术:从基础到设计模式
C++多线程管理的艺术:从基础到设计模式
110 0
|
7月前
|
设计模式 缓存 编译器
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
120 0

热门文章

最新文章

  • 1
    设计模式转型:从传统同步到Python协程异步编程的实践与思考
    59
  • 2
    C++一分钟之-设计模式:工厂模式与抽象工厂
    47
  • 3
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    54
  • 4
    C++一分钟之-C++中的设计模式:单例模式
    65
  • 5
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    43
  • 6
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    70
  • 7
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    62
  • 8
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    43
  • 9
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    52
  • 10
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    121