【C++设计模式】(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

server/2024/10/8 23:14:28/

文章目录

  • (四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。工厂模式的动机在于通过一个专门的工厂类来封装对象的创建过程,以解耦对象的使用和创建,隐藏复杂的对象实例化逻辑,从而提高代码的灵活性和可维护性。通过工厂模式,客户端代码只需与工厂接口或抽象类交互,而不必直接与具体类耦合,这使得系统更易于扩展和修改。

工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式。

简单工厂模式

简单工厂模式(不属于GoF的23种设计模式):工厂类根据输入的参数决定创建哪一种产品类的实例。

#include <iostream>
#include <string>// 抽象产品类
class Product {
public:virtual void operation() = 0;virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};// 具体产品类 A
class ConcreteProductA : public Product {
public:void operation() override {std::cout << "ConcreteProductA operation." << std::endl;}
};// 具体产品类 B
class ConcreteProductB : public Product {
public:void operation() override {std::cout << "ConcreteProductB operation." << std::endl;}
};// 简单工厂类
class SimpleFactory {
public:// 静态工厂方法,根据传入的字符串类型创建具体的产品对象static Product* createProduct(const std::string& type) {if (type == "A") {return new ConcreteProductA();  // 创建并返回 ConcreteProductA 对象} else if (type == "B") {return new ConcreteProductB();  // 创建并返回 ConcreteProductB 对象} else {return nullptr;        // 如果传入的类型无效,返回空指针}}
};int main() {// 使用简单工厂创建产品 AProduct* productA = SimpleFactory::createProduct("A");if (productA) {productA->operation();delete productA;}// 使用简单工厂创建产品 BProduct* productB = SimpleFactory::createProduct("B");if (productB) {productB->operation();delete productB;}return 0;
}

以上代码通过引入一个工厂类SimpleFactory ,将产品对象AB 的创建过程封装在工厂方法中,从而实现对象创建与使用的分离。客户端只需要通过工厂来获取对象,无需了解对象的创建细节。

工厂方法模式

简单工厂违反了开闭原则(对扩展开放,对修改关闭),因为每当需要引入新产品时,都需要修改工厂类。为了避免这个问题,工厂方法模式定义一个抽象工厂类,通过继承得到可以创建不同产品的工厂。

示例

#include <iostream>
#include <string>// 抽象产品类
class Product {
public:virtual void operation() = 0;virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};// 具体产品类 A
class ConcreteProductA : public Product {
public:void operation() override {std::cout << "ConcreteProductA operation." << std::endl;}
};// 具体产品类 B
class ConcreteProductB : public Product {
public:void operation() override {std::cout << "ConcreteProductB operation." << std::endl;}
};// 抽象工厂类
class Factory {
public:virtual Product* createProduct() = 0;virtual ~Factory() {}  // 虚析构函数,确保正确释放资源
};// 具体工厂类 A,创建 ConcreteProductA
class ConcreteFactoryA : public Factory {
public:Product* createProduct() override {return new ConcreteProductA();}
};// 具体工厂类 B,创建 ConcreteProductB
class ConcreteFactoryB : public Factory {
public:Product* createProduct() override {return new ConcreteProductB();}
};int main() {// 使用具体工厂类 A 创建产品 AFactory* factoryA = new ConcreteFactoryA();Product* productA = factoryA->createProduct();productA->operation();delete productA;delete factoryA;// 使用具体工厂类 B 创建产品 BFactory* factoryB = new ConcreteFactoryB();Product* productB = factoryB->createProduct();productB->operation();delete productB;delete factoryB;return 0;
}

这段代码通过定义一个抽象工厂类Factory来声明创建产品对象的接口,具体的产品创建由具体工厂类(ConcreteFactoryAConcreteFactoryB)来实现。工厂方法模式能在不修改已有代码的情况下,通过增加新的工厂类来创建新的产品类型,实现对开闭原则的遵循。

抽象工厂模式

抽象工厂模式的主要是为了解决在不需要指定具体类的情况下,创建一组相关或依赖对象 (产品族)的需求。它通过提供一个接口来创建一系列相关或依赖对象的工厂,使得客户端可以在不指定具体实现类的情况下,创建产品族中的产品。

#include <iostream>
#include <string>// 抽象产品 A 类
class ProductA {
public:virtual void operation() = 0;virtual ~ProductA() {}  // 虚析构函数,确保正确释放资源
};// 具体产品 A1
class ConcreteProductA1 : public ProductA {
public:void operation() override {std::cout << "ConcreteProductA1 operation." << std::endl;}
};// 具体产品 A2
class ConcreteProductA2 : public ProductA {
public:void operation() override {std::cout << "ConcreteProductA2 operation." << std::endl;}
};// 抽象产品 B 类
class ProductB {
public:virtual void operation() = 0;virtual ~ProductB() {} 
};// 具体产品 B1
class ConcreteProductB1 : public ProductB {
public:void operation() override {std::cout << "ConcreteProductB1 operation." << std::endl;}
};// 具体产品 B2
class ConcreteProductB2 : public ProductB {
public:void operation() override {std::cout << "ConcreteProductB2 operation." << std::endl;}
};// 抽象工厂类
class AbstractFactory {
public:virtual ProductA* createProductA() = 0;virtual ProductB* createProductB() = 0;virtual ~AbstractFactory() {} 
};// 具体工厂 1,创建产品 A1 和 B1
class ConcreteFactory1 : public AbstractFactory {
public:ProductA* createProductA() override {return new ConcreteProductA1();}ProductB* createProductB() override {return new ConcreteProductB1();}
};// 具体工厂 2,创建产品 A2 和 B2
class ConcreteFactory2 : public AbstractFactory {
public:ProductA* createProductA() override {return new ConcreteProductA2();}ProductB* createProductB() override {return new ConcreteProductB2();}
};int main() {// 使用具体工厂 1 创建产品 A1 和 B1AbstractFactory* factory1 = new ConcreteFactory1();ProductA* productA1 = factory1->createProductA();ProductB* productB1 = factory1->createProductB();productA1->operation();productB1->operation();delete productA1;delete productB1;delete factory1;// 使用具体工厂 2 创建产品 A2 和 B2AbstractFactory* factory2 = new ConcreteFactory2();ProductA* productA2 = factory2->createProductA();ProductB* productB2 = factory2->createProductB();productA2->operation();productB2->operation();delete productA2;delete productB2;delete factory2;return 0;
}

http://www.ppmy.cn/server/126150.html

相关文章

②无需编程 独立通道 Modbus主站EtherNet/IP转ModbusRTU/ASCII工业EIP网关串口服务器

Modbus主站EtherNet/IP转ModbusRTU/ASCII工业EIP网关串口服务器https://item.taobao.com/item.htm?ftt&id743840591638 EtherNet/IP 串口网关 EtherNet/IP 转 RS485 产品的配置和参数设置&#xff08;接上一章&#xff09; MS-A1-20X1 串口网关通过 EtherNet/IP 协议与…

SpringCloud-Netflix第一代微服务快速入门

1.springCloud常用组件 Netflix Eureka 当我们的微服务过多的时候&#xff0c;管理服务的通信地址是一个非常麻烦的事情&#xff0c;Eureka就是用来管理微服务的通信地址清单的&#xff0c;有了Eureka之后我们通过服务的名字就能实现服务的调用。 Netflix Ribbon\Feign : 客…

极狐GitLab 签约比博斯特,助力新能源智能底盘企业研发提效

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 相关客户案例 极狐GitLab 客户案例中心 客户背景 总部位于上…

C++ 部署深度学习模型的学习路线

随着深度学习模型在各行各业中的广泛应用&#xff0c;C 作为一门高效的系统编程语言&#xff0c;在深度学习模型的部署上具有极大的优势。相比 Python&#xff0c;C 在推理速度和资源管理方面表现更好&#xff0c;因此常被用于生产环境中的模型部署。然而&#xff0c;要使用 C …

Python | Leetcode Python题解之第448题找到所有数组中消失的数字

题目&#xff1a; 题解&#xff1a; class Solution:def findDisappearedNumbers(self, nums: List[int]) -> List[int]:n len(nums)for num in nums:x (num - 1) % nnums[x] nret [i 1 for i, num in enumerate(nums) if num < n]return ret

C++ 游戏开发

C游戏开发 C 是一种高效、灵活且功能强大的编程语言&#xff0c;因其性能和控制能力而在游戏开发中被广泛应用。许多著名的游戏引擎&#xff0c;如 Unreal Engine、CryEngine 和 Godot 等&#xff0c;都依赖于 C 进行核心开发。本文将详细介绍 C 在游戏开发中的应用&#xff0…

微信小程序——婚礼邀请函

目的 1.掌握微信小程序的开发技术&#xff0c;包括页面布局、交互设计、数据存储等。 2.学会运用微信小程序的各种组件和 API&#xff0c;实现个性化的婚礼邀请函功能。 3.通过制作婚礼邀请函小程序&#xff0c;提升创意设计和用户体验优化的能力。 4.了解如何在小程序中整…

【C++】第一节:C++入门

1、C关键字 2、命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&am…