简单工厂,工厂方法,抽象工厂模式

文章目录

  • 简单工厂模式
    • 简单工厂模式的角色
    • 简单工厂的介绍
  • 工厂方法
    • UML图片
    • 代码
    • 工厂方法总结:
  • 抽象工厂
    • 代码实现

简单工厂模式

简单工厂模式(Simple Factory Pattern)专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。

简单工厂模式,是一种实例化对象的方式,只要输入需要实例化对象的名字,就可以通过工厂对象的相应工厂函数来制造你需要的对象。

简单工厂模式的角色

(1)Factory工厂角色(工厂类):

工厂角色即工厂类,是简单工厂模式的核心,负责创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需要的产品对象。

(2)Product(抽象产品角色):

抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公告接口。所创建的具体产品对象都是其子类对象。

(3)ConcreteProduct(具体产品角色):

具体产品角色是简单工厂模式的创建目标。每个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的方法。

简单工厂的介绍

简单工厂(Simple Factory)不属于标准的OOP设计模式中的一项,在编写大型C++软件的时候,代码里面会出现很多的类,每次创建对象的时候,都需要通过new 类名称的方式来生成对象,这样一来,用户需要记忆很多类的名称,暂且不管记不记得住,这样的设计使得代码很难维护,类名如果做了改变,那么所有使用类名称的地方都需要去修改,耦合性太强,不符合我们软件设计的思想,Simple Factory就是在这样的需求下诞生的。

在这里插入图片描述

我们把对象的创建全部都封装在了SimpleFactory的create方法中,在这里我们传入一个Product就可以创建一个对象,省略了new的过程

#include <iostream>
#include <string>
using namespace std;
//产品类型的声明,抽象产品
class  Product
{
public:Product(string name) : ProductName(name) {};virtual void show() = 0;
protected:string ProductName;
};//具体产品的声明
class BaoMa :public Product
{
public:BaoMa(string name) : Product(name) {};void show(){std::cout << "This is BaoMa Product" << char(10);std::cout << ProductName << char(10);}
};//具体产品2 的申明
class BengChi :public Product
{
public:BengChi(string name) : Product(name) {};void show(){std::cout << "This is <BengChi> Product" << char(10);std::cout << ProductName << char(10);}
};enum ProductType
{BWM,BC
};class SimpleFactory
{
public://通过传入的枚举类型,创建对应的对象,返回对象的基类指针Product* createProduct(ProductType type){switch (type){case BWM:return new BaoMa("宝马");break;case BC:return new BengChi("奔驰");break;default:std::cout << "你输入了错误的名字" << type << char(10);break;}}
};int main()
{//创建简单工厂的实例SimpleFactory sf;unique_ptr<Product> p1(sf.createProduct(BWM));unique_ptr<Product> p2(sf.createProduct(BC));p1->show();p2->show();return 0;
}

工厂方法

UML图片

在这里插入图片描述

通过产生具体的工厂创建具体的产品,做到了在扩充新产品时,能够达到软件设计的“开-闭”原则

代码

#include <iostream>
#include <string>
using namespace std;class AbstractProduct
{
public:AbstractProduct(string name): _name(name){}//模拟产品对象的抽象方法virtual void show() = 0;
protected:string _name;
};class ProductA:public AbstractProduct
{
public://其实这是一个委托构造函数ProductA(string name) : AbstractProduct(name) {}void show() { std::cout << "这是一个产品A的对象"; char(10);std::cout << "string name : " << _name << char(10);}
};class ProductB :public AbstractProduct
{
public://其实这是一个委托构造函数ProductB(string name) : AbstractProduct(name) {}void show() { std::cout << "这是一个产品B的对象"<< char(10);std::cout << "string name : " << _name << char(10);}
};//定义枚举类型的数据
enum  ProductType
{XIAOMI,HUAWEI,
};//定义抽象工厂
class AbstractFactory
{
public:virtual AbstractProduct* createProduct() = 0;
};//小米手机工厂
class XiaoMiFactory:public AbstractFactory
{
public:AbstractProduct* createProduct(){std::cout << "调用了小米工厂的创建方法" << char(10);return new ProductA("小米手机");}
};//华为手机工厂
class HuaWeiFactory :public AbstractFactory
{
public:AbstractProduct* createProduct(){std::cout << "调用了华为工厂的创建方法" << char(10);return new ProductB("华为手机");}
};int main()
{//在这里我们使用智能指针,创建具体工厂unique_ptr<AbstractFactory> Fac1(new XiaoMiFactory);unique_ptr<AbstractFactory> Fac2(new HuaWeiFactory);//通过工厂方法创建产品unique_ptr<AbstractProduct> Pro1(Fac1->createProduct());unique_ptr<AbstractProduct> Pro2(Fac2->createProduct());Pro1->show();Pro2->show();return 0;
}

工厂方法可以解决一簇产品(一款产品有多种形态)的问题,并且工厂一次只能生产一种产品;但需要一个工厂能够同时生产多款产品时,则需要用到抽象工厂模式

工厂方法总结:

仔细理解上面的工厂方法模式,会发现一个问题,就是每一个实例工厂负责生产一个实例产品,也就是一个产品对应一个工厂,一个工厂对应一个产品,那么小米不仅仅生产手机,还生产耳机,智能手环,智能插座等等相关的小米产品簇,不可能给这每一个产品都创建一个工厂类,那样的话代码中的类就太多了,不好维护,而且也不符合实际情况。

实际上小米或者华为的工厂里面,有相关联的产品簇都是在一个工厂完成创建的;BMW或者Audi汽车制造工厂除了生产汽车,生产线上也有可能生产轮胎,或者其它的汽车附属产品。

所以对于包含产品簇这么一类实体关系的设计,就需要使用Abstract Factory抽象工厂了,你也可以把上面的工厂方法看作只生产一种产品的抽象工厂,本质是相同的。

抽象工厂

在这里插入图片描述

可以看到,抽象工厂模式把一个产品簇的产品放在一个工厂类中去创建,不仅大大减少了工厂类的个数,更符合现实中工厂生产产品的模式。根据上面的内容描述,仔细思考简单工厂,工厂方法和抽象工厂的区别联系

代码实现

#include <iostream>
using namespace std;//抽象产品 手机类
class AbstractPhone
{
public:AbstractPhone(string name) : _name(name) {};//模拟产品对象的一个抽象的方法virtual void show() = 0; 
protected:string _name;
};//产品实体类型 小米
class XiaoMiPhone: public AbstractPhone
{
public:XiaoMiPhone(string name) : AbstractPhone(name) {};void show(){std::cout << "这是" << _name << "手机" << char(10);}
};//产品实体类型 华为
class HuaweiPhone : public AbstractPhone
{
public:HuaweiPhone(string name) : AbstractPhone(name) {};void show(){std::cout << "这是" << _name << "手机" << char(10);}
};//抽象产品 手环
class AbstractCircle
{
public:AbstractCircle(string name) : _name(name) {};//模拟产品对象的一个抽象的方法virtual void show() = 0;
protected:string _name;
};//产品实体 小米手环
class  XiaoMiCircle:public AbstractCircle
{
public:XiaoMiCircle(string name) :AbstractCircle(name) {};void show(){std::cout << "这是" << _name << "手环" << char(10);}
};//产品实体 华为手环
class  HuaWeiCircle :public AbstractCircle
{
public:HuaWeiCircle(string name) :AbstractCircle(name) {};void show(){std::cout << "这是" << _name << "手环" << char(10);}
};//抽象工厂,创建一个产品族的设备的产品
class AbstractFactory
{
public://创建手机的纯虚函数virtual AbstractPhone* createPhone() = 0;virtual AbstractCircle* createCircle() = 0;
};//生产小米的工厂
class XiaoMiFactory:public AbstractFactory
{
public:virtual AbstractPhone* createPhone(){return new XiaoMiPhone("小米14Pro");}virtual AbstractCircle* createCircle(){return new XiaoMiCircle("小米手环NFC版本");}
};//生产华为的工厂
class HuaWeiFactory :public AbstractFactory
{
public:virtual AbstractPhone* createPhone(){return new XiaoMiPhone("华为Mate60 pro");}virtual AbstractCircle* createCircle(){return new XiaoMiCircle("华为GT Runing");}
};int main()
{//利用智能指针,创建生产的工厂unique_ptr< AbstractFactory> fac1(new XiaoMiFactory);unique_ptr< AbstractFactory> fac2(new HuaWeiFactory);//通过工厂来生产手机的unique_ptr< AbstractPhone > phone1(fac1->createPhone());unique_ptr< AbstractPhone > phone2(fac2->createPhone());phone1->show();phone2->show();//生产手环unique_ptr< AbstractCircle > cir1(fac1->createCircle());unique_ptr< AbstractCircle > cir2(fac2->createCircle());cir1->show();cir2->show();return 0;
}

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

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

相关文章

【数据库原理】(5)关系数据库的关系数据结构

关系及相关概念 在关系模型中,无论是实体还是实体之间的联系均由关系(二维表)来表示。 1.域&#xff08;Domain&#xff09; 定义&#xff1a;域是一组具有相同数据类型的值的集合。例子&#xff1a;实数集合、整数集合、英文字母集合等。 2.笛卡儿积&#xff08;Cartesian…

项目框架构建之3:Nuget服务器的搭建

本文是“项目框架构建”系列之3&#xff0c;本文介绍一下Nuget服务器的搭建&#xff0c;这是一项简单的工作&#xff0c;您或许早已会了。 1.打开vs2022创建Asp.net Web应用程序 框架选择.net framework4.8&#xff0c;因为nuget服务器只支持.net framework。 2.选择空项目和去…

【Linux系统编程二十六】:线程控制与线程特性(Linux中线程库/线程创建/线程退出/线程等待)

【Linux系统编程二十六】&#xff1a;线程控制与线程特性 一.Linux线程库pthread1.线程控制块2.线程tid3.线程栈 二.线程控制1.线程创建2.线程退出3.线程等待 三.线程的特性1.独立栈2.局部存储3.线程可分离 一.Linux线程库pthread 在Linux中&#xff0c;是没有明确的线程概念的…

进程与计划任务

什么是程序&#xff1f; 程序&#xff1a;在硬盘上躺着&#xff0c;执行特定任务的一串代码 静态 进程&#xff1a;加载到内存中运行 动态 进程是程序的副本&#xff0c;进程是有生命周期&#xff0c;是硬件资源分配的最小单位 pid号可以通过pstree -p 查到 uid &…

卫星互联网与MEC融合方案研究

卫星互联网与MEC融合方案研究 作者&#xff1a;温特、王立中、司鹏、颜明明、马恬、郭伊蒙 中国卫通集团股份有限公司 本文首发&#xff1a;第十九届卫星通信学术年会 摘 要&#xff1a;在卫星互联网中引入移动边缘计算(MEC)技术可有效提高用户体验质量&#xff0c;降低运营成…

NSSCTF 简单包含

开启环境: 使用POST传flag&#xff0c;flag目录/var/www/html/flag.php 先使用post来尝试读取该flag.php 没反应: 查看一下源码index.php&#xff0c;看有什么条件 base64解密: <?php$path $_POST["flag"];if (strlen(file_get_contents(php://input)) <…

动手学深度学习之卷积神经网络之池化层

池化层 卷积层对位置太敏感了&#xff0c;可能一点点变化就会导致输出的变化&#xff0c;这时候就需要池化层了&#xff0c;池化层的主要作用就是缓解卷积层对位置的敏感性 二维最大池化 这里有一个窗口&#xff0c;来滑动&#xff0c;每次我们将窗口中最大的值给拿出来 还是上…

docker 搭建gitlab 恢复和备份

最近一直在折腾gitlab 代码管理系统 采用docker搭建 镜像网址 https://hub.docker.com/ 技术交流 http://idea.coderyj.com/ 1.因为我要恢复的版本是12.0.9的所有我就下载了docker-ce的12.0.9的镜像 1.下载镜像 docker pull gitlab/gitlab-ce:12.0.9-ce.02.安装 docker run …

Vue v-html中内容图片过大自适应处理

之前图片如下&#xff0c;图片已经超出了页面的展示范围 对v-html增加样式处理 <div class"body padding-l scroll " v-html"docData.content"> </div><style scoped>.body >>> img {max-width: 100% ;} </style>…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)添加 删除 修改 释放

在上篇文章&#xff08;处理任务队列中的任务&#xff09;中我们讲解了处理任务队列中的任务的具体流程&#xff0c;eventLoopProcessTask函数的作用&#xff1a; 处理队列中的任务&#xff0c;需要遍历链表并根据type进行对应处理,也就是处理dispatcher中的任务。 // 处理任…

很实用的ChatGPT网站—在线编程模块增补篇

很实用的ChatGPT网站&#xff08;http://chat-zh.com/&#xff09;——增补篇 今天介绍一个好兄弟开发的ChatGPT网站&#xff0c;网址[http://chat-zh.com/]。这个网站功能模块很多&#xff0c;包含生活、学习、医疗、法律、经济等很多方面。今天跟大家分享一下&#xff0c;新…

使用 Process Explorer 和 Windbg 排查软件线程堵塞案例分享

目录 1、问题说明 2、线程堵塞的可能原因分析 3、使用Windbg和Process Explorer确定线程中发生了死循环 4、根据Windbg中显示的函数调用堆栈去查看源码&#xff0c;找到问题 4.1、在Windbg定位发生死循环的函数的方法 4.2、在Windbg中查看变量的值去辅助分析 4.3、是循环…