C++之工厂模式

news2024/11/15 5:43:36

目录

一、为什么要使用工厂模式

优点

缺点

二、简单工厂(Simple Factory)

好处:

不足:

三、工厂方法:

好处:

不足:

四、抽象工厂(Abstract   Factory)


一、为什么要使用工厂模式

主要是对对象的创建进行了一个封装;
因此也属于创建型模式。

目的:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

优点

  1. 一个调用者想创建一个对象,只要知道其名称就可以了;
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;
  3. 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

二、简单工厂(Simple Factory)

把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象

好处:

可以看到,简单工厂可以做到,让用户创建对象的时候只需要知道对象的名称(BMWAUDI)就好,而不需要关心创建对象的细节(BMW是如何建造的、型号是什么等等细节)。

不足:


每当我们想要扩展对象的时候(增加BENZ的对象)就需要在SimpleFactory类中添加代码,增加switch后面的case选项。这样一来,就需要修改源代码。灵活性非常的差!!!

那么,能不能做到添加对象的时候,不对现有代码进行修改呢?(也就是我们开发软件时候需要遵守的开-闭原则)

这便是接下来工厂方法

三、工厂方法:

一个派生类就代表着一个工厂,每个工厂都有具体要生产的产品。

FActory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品,

//工厂方法:
class Factory
{
public:
	virtual Car* createCar(string name) = 0;
};
//宝马工厂
class BMWFactory : public Factory
{
public:
	Car* createCar(string name) 
	{
		return new BMW(name);
	}
};
//奥迪工厂
class AudiFactory : public Factory
{
public:
	Car* createCar(string name)
	{
		return new Audi(name);
	}
};

void main()
{
	Factory* bmwfty = new BMWFactory();
	Factory* audifty = new AudiFactory();

	Car* p1 = bmwfty->createCar("X6");
	Car* p2 = audifty->createCar("A6");

	p1->show();
	p2->show();
}

当我们想要增加新的工厂:比如说奔驰工厂的时候,根本不用去管宝马和奥迪,只需要增加一个新的工厂就行了,所以说是符合了软件设计的          “开闭原则”   : 对已有的功能关闭,对扩展开放

好处:

可以做到不同的产品,在不同的工厂里面创建(模块化非常清晰),能够对现有工厂,以及产品的修改关闭

不足:

实际上,很多产品是有关联关系的,属于一个产品簇,不应该放到不同的工厂里面去创建,这样
一是不符合实际的产品对象创建逻辑,二是工厂类太多了,不好维护

四、抽象工厂(Abstract   Factory)

应用于有关联关系的产品

上面的简单工厂已经能够满足基本的要求了,但是在实际生活中,比如宝马企业,不止有汽车,还有别的系列产品,比如:车灯、轮胎。。。也就是跟汽车有关的一组产品

代码

继承关系如下:

//系列产品1:
class Car 
{
public:
	Car(string name):_name(name)
	{}
	virtual void show()
	{}

protected:
	std::string _name;
};

class BMW:public Car
{
public:
	BMW(string name):Car(name)
	{}
	void show() {
		cout << "这是一辆宝马" << endl;
	}
};

class Audi :public Car
{
public:
	Audi(string name) :Car(name)
	{}
	void show() {
		cout << "这是一辆奥迪" << endl;
	}
};
//系列产品 2:
class Light
{
public:
	virtual void show()
	{
	}
};
class BmwLight :public Light
{
public:
	void show()
	{
		cout << "BMW 的 Light" << endl;
	}
};
class AudiLight :public Light
{
public:
	void show()
	{
		cout << "Audi 的 Light" << endl;
	}
};

抽象工厂的实现:

//工厂方法 ==>> 抽象工厂(对一组关联关系的产品簇提供产品对象的统一创建)
class AbstractFactory
{
public:
	virtual Car* createCar(string name) = 0;//工厂方法  创建汽车
	virtual Light* createLight() = 0;// 工厂方法  创建汽车关联的产品,车灯
};
//宝马工厂
class BMWFactory : public AbstractFactory
{
public:
	Car* createCar(string name) 
	{
		return new BMW(name);
	}
	Light* createLight()
	{
		return new BmwLight();
	}
};
//奥迪工厂
class AudiFactory : public AbstractFactory
{
public:
	Car* createCar(string name)
	{
		return new Audi(name);
	}
	Light* createLight()
	{
		return new AudiLight();
	}
};

使用:

void main()
{
	AbstractFactory* bmwfty = new BMWFactory();
	AbstractFactory* audifty = new AudiFactory();

	Car* p1 = bmwfty->createCar("X6");
	Car* p2 = audifty->createCar("A6");
	p1->show();
	p2->show();

	Light* l1 = bmwfty->createLight();
	Light* l2 = audifty->createLight();
	l1->show();
	l2->show();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RWA 成下一轮加密大叙事,PoseiSwap 的价值正在凸显

PoseiSwap是Nautilus Chain上的首个DEX&#xff0c;在Nautilus Chain模块化开发的支持下&#xff0c;PoseiSwap能够以更具延展性的方式来构建应用&#xff0c;并能够为交易者提供极佳的交易体验。基于Nautilus Chain支持下的Zk-Rollup方案&#xff0c;PoseiSwap构建了基于零知识…

文心一言 VS 讯飞星火 VS chatgpt (45)-- 算法导论6.1 3题

三、证明:在最大堆的任一子树中&#xff0c;该子树所包含的最大元素在该子树的根结点上。 文心一言&#xff1a; 在最大堆中&#xff0c;根结点是整个堆中最大元素的孩子&#xff0c;因此它包含的最大元素是在该子树的根结点上。 我们可以通过递归的方式证明任意子树中的最大…

C++11 线程库—互斥锁

前言 多线程因其调度的随机性和时间片分配&#xff0c;如果没有限制的访问临界资源&#xff0c;会导致出现无法预测的结果&#xff0c;也无法达到预期。 所以&#xff0c;访问临界区&#xff0c;需要是原子性的&#xff0c;在一个线程完成之前&#xff0c;不能有其他线程访问&…

找bug号召

我的博客是为了完成这个找 bug 号召&#xff1a; https://bbs.csdn.net/topics/614134877。 文章目录 测试场景之三&#xff1a; 选择你的身份 测试场景之三&#xff1a; 选择你的身份 同样在个人中心的最下面&#xff0c;你可以看到身份选择的界面。 注意&#xff0c;你要把鼠…

Python元组、集合、字典(超详细举例、讲解和区分)

总有一天你要一个人在暗夜中&#xff0c;向那座桥走过去 文章目录 一、元组 字符串、元组、列表的总结 二、集合 1.定义空集合 2.创建集合 &#xff08;1&#xff09;直接创建 &#xff08;2&#xff09;set函数 3.列表、元组、字符串、字典的去重 4.向集合中添加元素…

python---js逆向------再接再励------案例

作者前言 这是我的gitee仓库:https://gitee.com/qin-laoda/python-exercises 有兴趣的小可爱们可以点进去看看, 目录 常见的js加密算法 微信公众号的简单案例 ________________________________ 鉴于有一些小可爱对于js逆向的理解还有一些不解,下面我会再进一步的介绍js…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(6月 23 日论文合集)

文章目录 一、检测相关(4篇)1.1 Targeted collapse regularized autoencoder for anomaly detection: black hole at the center1.2 RXFOOD: Plug-in RGB-X Fusion for Object of Interest Detection1.3 Toward Automated Detection of Microbleeds with Anatomical Scale Loca…

axios简单使用

axios简单使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wid…

【杂谈】过往时期2-嵌入式求学故事线简忆

前一篇文章 过往时期 - 欢迎来到 Staok - 瞰百易 (gitee.io)。 在我兴趣广泛的过去&#xff0c;关于嵌入式方面的经历啊&#xff0c;讲一条这个的故事线。 小学&#xff0c;电子积木&#xff0c;灯泡&#xff0c;电机&#xff0c;上电发光、风扇旋转&#xff0c;风扇转的快了还…

AnyLogic仿真软件 8.8.2 Crack

AnyLogic仿真软件用于以下行业&#xff1a; 供应链 制造业 运输 仓库运营 铁路物流 矿业 石油和天然气 港口及码头 更多行业 为什么要进行仿真建模&#xff1f; 无风险环境 仿真建模提供了一种安全的方法来测试和探索不同的“假设”场景。在做出现实世界的改变之前做出正确的决…

第10章 隐式转换

第10章 隐式转换 package chapter10object Test01_TestImplicit {def main(args: Array[String]): Unit {val richInt new MyRichInt(12)println(richInt.myMax(15))// 1. 隐式函数implicit def convert(num: Int): MyRichInt new MyRichInt(num)println(12.myMax(15))// 2.…

登录校验原理过程和统一拦截技术(Cookie、Sesstion 和JWT令牌)

一、登录校验 问题&#xff1a;在未登录情况下&#xff0c;我们也可以直接访问部门管理、员工管理等功能。由于浏览器与web服务器中的数据交互是通过HTTP协议的&#xff0c;而HTTP协议是无状态的–即每个页面中的请求和响应都是独立的&#xff0c;没有状态存在。所以我们需要进…

【数据库】关系型数据库与非关系型数据库解析

【数据库】关系型数据库与非关系型数据库解析 文章目录 【数据库】关系型数据库与非关系型数据库解析1. 介绍2. 关系型数据库3. 非关系型数据库4. 区别4.1 数据存储方式不同4.2 扩展方式不同4.3 对事务性的支持不同4.4 总结 参考 1. 介绍 一个通俗易懂的比喻&#xff1a;关系型…

Xpath介绍以及语法

Xpath介绍 XML路径语言&#xff08;XML Path Language&#xff09;&#xff0c;它是一种用来确定XML文档中某部分位置的语言。 XPath基于XML的树状结构&#xff0c;提供在数据结构树中找寻节点的能力。 起初XPath的提出的初衷是将其作为一个通用的、介于XPointer与XSL间的语法模…

第8章 模式匹配

第8章 模式匹配 基本概念和用法 模式守卫 package chapter08object Test01_PatternMatchBase {def main(args: Array[String]): Unit {// 1. 基本定义语法val x 5val y x match {case 1 > "one"case 2 > "two"case 3 > "three"ca…

《Reinforcement Learning: An Introduction》第6章笔记

Chapter 6 Temporal-Difference Learning If one had to identify one idea as central and novel to reinforcement learning, it would undoubtedly be temporal-difference (TD) learning. 时序差分学习&#xff08;temporal-difference (TD) learning&#xff09;组合了Mon…

PID控制算法 – 0、PID原理

1、开局一张图 很多地方都觉得PID的控制结构示意图是这样的&#xff1a; 2、目标值&#xff08;Setpoint&#xff09;、输入值&#xff08;Input&#xff09;、误差&#xff08;Error&#xff09; 其实把上图那个输入改为目标值&#xff08;Setpoint&#xff09;更合适&#…

canvas详解08-基本动画

由于我们是用 JavaScript 去操控 canvas 对象,这样要实现一些交互动画也是相当容易的。在本章中,我们将看看如何做一些基本的动画。 可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费…

CoreMark 跑个分:OrangePi5 RK3588S

一、 Orange Pi 5 简介 Orange Pi 5 采用了瑞芯微 RK3588S 新一代八核 64 位处理器&#xff0c;具体为四核A76四核A55&#xff0c;采用了 8nm 工艺设计&#xff0c;主频最高可达 2.4GHz&#xff0c;集成 ARM Mali-G610 MP4 GPU&#xff0c;内嵌高性能 3D 和 2D 图像加速模块&am…

【python桌面应用设计】tkinter库 01. Tkinter程序设计思想和结构(保姆级代码注释)

目录 实现思路代码实战简单的基础结构示例稍微丰富一点的示例 总结 『python图形化GUI界面设计』分享tkinter库、PyQt5库、wxPython库等相关的新手入门教程&#xff0c;目标是编写python程序时可以给程序一个可视化界面。 欢迎关注 『python桌面应用设计』 系列&#xff0c;持续…