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

embedded/2024/11/25 8:25:44/

动机

在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。

如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种封装机制来避免客户程序和这种具体对象创建工作的紧耦合?

代码示例:

MainForm方法调用Splitter将东西进行切分,有二进制文件切分、txt文件切分、图片文件切分、视频文件切分。

第一版:ISplitter * splitter= new BinarySplitter();这种写法依赖于具体类,违反依赖倒置原则(高层模块不应该依赖于低层模块,而是应该依赖于抽象。同时,抽象不应该依赖于具体实现,具体实现应该依赖于抽象。由编译时处理换成运行时处理)

// 抽象基类
class ISplitter{
public:virtual void split()=0;virtual ~ISplitter(){}
};class BinarySplitter : public ISplitter{};class TxtSplitter: public ISplitter{};class PictureSplitter: public ISplitter{};class VideoSplitter: public ISplitter{};class MainForm : public Form
{TextBox* txtFilePath;TextBox* txtFileNumber;ProgressBar* progressBar;public:void Button1_Click(){ISplitter * splitter= new BinarySplitter();//依赖具体类splitter->split();}
};

第二版:具体调用工厂,MainForm不依赖于具体的类,而是依赖于抽象类和工厂基类。

class MainForm : public Form
{SplitterFactory*  factory;//工厂public:MainForm(SplitterFactory*  factory){this->factory=factory;}void Button1_Click(){ISplitter * splitter=factory->CreateSplitter(); //多态newsplitter->split();}
};

ISplitterFactory


//抽象类
class ISplitter{
public:virtual void split()=0;virtual ~ISplitter(){}
};//工厂基类
class SplitterFactory{
public:virtual ISplitter* CreateSplitter()=0;  // 创建对象virtual ~SplitterFactory(){}
};

FileSplitter文件:几个具体的工厂继承自SplitterFactory,实现虚函数,实现具体类的创建

//具体类
class BinarySplitter : public ISplitter{};class TxtSplitter: public ISplitter{};class PictureSplitter: public ISplitter{};class VideoSplitter: public ISplitter{};//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:virtual ISplitter* CreateSplitter(){return new BinarySplitter();}
};class TxtSplitterFactory: public SplitterFactory{
public:virtual ISplitter* CreateSplitter(){return new TxtSplitter();}
};class PictureSplitterFactory: public SplitterFactory{
public:virtual ISplitter* CreateSplitter(){return new PictureSplitter();}
};class VideoSplitterFactory: public SplitterFactory{
public:virtual ISplitter* CreateSplitter(){return new VideoSplitter();}
};

工厂方法定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。

具体到上面的代码,用于创建对象的接口SplitterFactory,让子类(BinarySplitterFactory,TxtSplitterFactory等具体工厂)决定实例化哪一个类。

在下列情况下可以使用Factory Method模式:
• 当一个类不知道它所必须创建的对象的类的时候。
• 当一个类希望由它的子类来指定它所创建的对象的时候。
• 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。(classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.)


http://www.ppmy.cn/embedded/140338.html

相关文章

Vue前端进阶面试题目(二)

虛拟 DOM 的解析过程是怎样的? 虚拟DOM(Virtual DOM)是Vue等现代前端框架为了提高页面渲染性能而采用的一种技术。其解析过程大致如下: 创建虚拟DOM树:当应用的状态发生变化时,会生成一个新的虚拟DOM树,…

Unity ShaderLab --- 实现局部透明

首先准备一张局部透明度的贴图 实现局部透明原理: 采样准备好的贴图,在片元着色中,将返回颜色的a值乘上采样后的a值 代码: fixed4 frag (v2f i) : SV_Target{fixed4 col i.color;col.a * tex2D(_MainTex, i.texcoord).a;return…

=computed() =ref()

computed() ref() 在 Vue 中,computed() 和 ref() 是 Vue 3 组合式 API 的核心工具,它们分别用于 计算属性 和 响应式数据。以下是它们的区别和用法: 1. ref() 作用 用于创建响应式的单一数据。可以是基本类型(如字符串、数字、…

RocketMQ 消息示例-延迟消息

生产者在确定一定时间间隔之后,这个消息才会被发送。其实也就是不会马上将消息发送出去,希望过一段时间以后再发送出去。 生产者在发送message的时候设置了一个延迟时间的等级,这里的3描述的是时间延迟的等级。这个消息会被延迟10s的时间 mes…

LeetCode-632. Smallest Range Covering Elements from K Lists [C++][Java]

目录 题目描述 解题思路 【C】 【Java】 LeetCode-632. Smallest Range Covering Elements from K Listshttps://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/description/ 题目描述 You have k lists of sorted integers in non-decreasing o…

Vscode进行Java开发环境搭建

Vscode进行Java开发环境搭建 搭建Java开发环境(Windows)1.Jdk安装2.VsCode安装3.Java插件4.安装 Spring 插件5.安装 Mybatis 插件5.安装Maven环境6.Jrebel插件7.IntelliJ IDEA Keybindings8. 收尾 VS Code(Visual Studio Code)是由微软开发的一款免费、开…

STM32完全学习——使用标准库完成PWM输出

一、TIM2初始化 我这里使用的是STM32F407ZGT6这个芯片,我这里使用的是定时器TIM2来完成PWM输出,由于这里没有使用中断,因此不需要初始化NVIC,下面先来进行定时器的相关初始化 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;R…

C#的数据类型总结:decimal ,double,float的区别

在 C# 中,decimal、double 和 float 都是用于表示数值类型的关键字,但它们在精度、范围和用途上有所不同。以下是它们的主要区别和适用场景的总结。 目录 1. decimal 2. double 3. float 主要比较 适用场景总结 注意点 1. decimal 类型大小: 16 字…