C++之工厂模式

目录

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

优点

缺点

二、简单工厂(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.hqwc.cn/news/1187.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软考网络管理员】2023年软考网管初级常见知识考点(10)- 网际协议IP及IPV6,IPV4详解

涉及知识点 分类的IP地址&#xff0c;子网划分&#xff0c;CIDR和路由汇聚&#xff0c;IPV4数据报格式&#xff0c;IPV6协议&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-《拄杖盲学…

数据分析案例-航空公司满意度数据可视化

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【算法之贪心算法IV】leetcode56. 合并区间

452. 用最少数量的箭引爆气球 力扣题目链接 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴…

IDEA字体配置

IDEA默认字体&#xff1a;JetBrains Mono 1、下载Monaco字体&#xff08;windows版&#xff09;&#xff1a;下载地址&#x1f448; 2、双击安装 3、在IDEA中切换Monaco字体

C++ DAY3

1.思维导图 2.有以下类定义&#xff0c;按要求实现剩余功能 #include <iostream> using namespace std;class Person { private:int age;int *p; public://无参构造Person():p(new int(89)){age 18;}//有参构造Person(int age,int num){this->age age;this->pne…

【MySQL】SQL的函数用法

文章目录 聚合函数Count()Max()Min()Sum()Avg() 其他常用函数时间函数字符串函数SUBSTRING函数:切割字符串([start:end])SUBSTRING_INDEX函数:切割字符串(split)LOWER&UPPER函数:大小写转化CONCAT&CONCAT_WS函数:连接字符串REPLACE函数:字符串替换 数学函数ROUND函数:四…

Spring Boot高阶篇笔记

一、Spring Boot整合Redis缓存 JSR-107、Spring缓存抽象、整合Redis 1、JSR107 Java Caching定义了5个核心接口&#xff0c;分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。 • CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应…

一点基础、但一直没分清的概念2023/06/28

文章目录 1.export和export default的区别2.npm和cnpm的区别3.npm run dev/serve的区别4.slice、splice和split的区别 1.export和export default的区别 模块功能主要由两个命令构成&#xff1a;export和import。export命令用于规定模块的对外接口&#xff0c;import命令用于输…

MySQL事务与存储引擎

MySQL事务与存储引擎 MySQL事务一、事务的概念二、事务的ACID特点1、原子性2、一致性3、隔离性4、持久性&#xff08;Durability&#xff09;总结 三、事务之间的相互影响1、脏读2、不可重复读3、幻读4、丢失更新 四、Mysql及事物隔离级别1、查询全局事务隔离级别2、查询会话事…

npm 包 - serve 使用

前端打包后&#xff0c;或者本地的html文件。有时需要将打包好的项目跑一下看看效果&#xff0c;这时就可以使用 serve 工具&#xff0c;在本地启动一个静态文件服务器。本文主要简单记录下 npm 包 serve 的基本使用命令。 一、全局安装 serve npm install serve -g二、运行 s…

文心一言眼里的Java世界

目录 一、Java基础教程系列二、先听听文心一言怎么说&#xff1f;三、话不多说&#xff0c;开干。1、要有一个正确的Java学习路线&#xff0c;做一个细致的Java学习规划。2、学习资料推荐3、书中自有黄金屋&#xff0c;书中自有颜如玉4、自学周期推荐5、效率为先6、哪吒的学习方…

【深度学习】2-1 神经网络 - 激活函数

激活函数 将输入信号的总和转换为输出信号&#xff0c;一般称为激活函数&#xff08;activation function&#xff09;。激活函数作用在于决定如何来激活输入信号的总和。 对激活函数&#xff0c;一般要求&#xff1a; 非线性&#xff1a;为提高模型的学习能力&#xff0c;如…