C++设计模式|创建型 3.抽象工厂模式

在上一篇文章中介绍了工厂模式,每个具体工厂负责生产一个专门的产品,其代码扩展性很好,这篇文章将介绍抽象工厂模式。

1.为什么要使用抽象工厂模式?

既然已经有了“工厂模式”,那为什么还会有抽象工厂模式呢?

这就涉及到创建“多类”对象了,在工厂方法模式中,每个具体工厂只负责创建单一的产品。但是如果有多类产品呢,比如说“手机”,一个品牌的手机有高端机、中低端机之分,这些具体的产品在工厂模式中都需要建立一个单独的工厂类,但是它们都是相互关联的,都共同属于同一个品牌,这就可以使用到【抽象工厂模式】。

抽象工厂模式可以确保一系列相关的产品被一起创建,这些产品能够相互配合使用,再举个例子,有一些家具,比如沙发、茶几、椅子,都具有古典风格的和现代风格的,抽象工厂模式可以将生产现代风格的家具放在一个工厂类中,将生产古典风格的家具放在另一个工厂类中,这样每个工厂类就可以生产一系列的家具

2.抽象工厂模式的基本结构

抽象工厂模式包含多个抽象产品类,多个具体产品类,一个抽象工厂接口和多个具体工厂类,给个具体工厂杜泽创建一组相关的产品。

  • 抽象产品接口AbstractProduct: 定义产品的接口,可以定义多个抽象产品接口,比如说沙发、椅子、茶几都是抽象产品。所谓抽象产品接口,其实就是表示生产产品的一个纯虚函数,具体实现由下面的具体产品类实现。
  • 具体产品类ConcreteProduct: 实现抽象产品接口,产品的具体实现,古典风格和沙发和现代风格的沙发都是具体产品。
  • 抽象工厂接口AbstractFactory: 声明一组用于创建产品的方法,每个方法对应一类产品。该接口也是纯虚函数,具体实现有具体工厂类完成。
  • 具体工厂类ConcreteFactory 实现抽象工厂接口,负责创建一组具体产品的对象,在本例中,生产古典风格的工厂和生产现代风格的工厂都是具体实例。

 下面可以根据具体代码再理解上面的内容。

3.C++抽象工厂模式

【设计模式专题之抽象工厂模式】3. 家具工厂 (kamacoder.com)icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=1077

题目描述:

小明家新开了两个工厂用来生产家具,一个生产现代风格的沙发和椅子,一个生产古典风格的沙发和椅子,现在工厂收到了一笔订单,请你帮他设计一个系统,描述订单需要生产家具的信息。

输入描述:

输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示订单的数量。 

接下来的 N 行,每行输入一个字符串,字符串表示家具的类型。家具类型分为 "modern" 和 "classical" 两种。

输出描述:

对于每笔订单,输出字符串表示该订单需要生产家具的信息。 

modern订单会输出下面两行字符串 

modern chair 

modern sofa

classical订单会输出下面两行字符串 

classical chair 

classical sofa

输入示例: 

3
modern
classical
modern

输出示例:

modern chair
modern sofa
classical chair
classical sofa
modern chair
modern sofa

在上面的示例中,工厂收到了3笔订单,其中有2笔要求生产modern风格,1笔要求生产classical风格。根据输入的类型,每次订单生产的家具信息被输出到控制台上。 

代码实现: 

1.多个抽象产品类和多个具体产品类

根据题目,生产的产品有椅子和沙发两种,每种产品有现代和古典两种风格,那个椅子和沙发会各自对应一个抽象产品类,而现代椅子和古典椅子,现代沙发和古典沙发将是这两个抽象产品类的具体产品类。代码如下:

//抽象椅子类,里面包含生产接口produce()
class Chair{
public://抽象产品生产接口virtual void produce() = 0;
};//具体现代风格椅子类
class ModernChair : public Chair{
public://多态实现具体抽象产品生产接口的具体化void produce() override{cout<<"modern chair"<<endl;}
};//具体古典风格椅子类
class ClassicalChair : public Chair{
public:
//多态实现具体抽象产品生产接口的具体化void produce() override{cout<<"classical chair"<<endl;}
};//抽象沙发类
class Sofa{
public:virtual void produce() = 0;
};//具体现代沙发类
class ModernSofa:public Sofa{
public:void produce() override{cout<<"modern sofa"<<endl;}
};//具体古典沙发类
class ClassicalSofa:public Sofa{
public:void produce() override{cout<<"classical sofa"<<endl;}
};

 2.一个抽象工厂类和多个具体工厂类

抽象工厂定义了生产产品的动作接口,具体工厂可以生产同风格的多种产品。

/下面是抽象工厂类,声明一组用于创建产品的方法,每个方法对应一种产品
class AbstractFurnitureFactory{
public:virtual Chair* createChair() = 0;virtual Sofa* createSofa() = 0;
};//有了抽象工厂,需要设计具体工厂类,每个类负责生产同一风格的多种不同产品//具体现代风格家具工厂类
class ModernFurnitureFactory:public AbstractFurnitureFactory{
public://生产现代风格的椅子Chair * createChair() override{return new ModernChair();}//生产现代风格的沙发Sofa* createSofa() override{return new ModernSofa();}};//具体古典风格家具工厂类
class ClassicalFurnitureFactory:public AbstractFurnitureFactory{
public://生产古典风格的椅子Chair * createChair() override{return new ClassicalChair();}//生产古典风格的沙发Sofa* createSofa() override{return new ClassicalSofa();}};

整体代码如下:

#include<iostream>
#include<string>
using namespace std;//生产的产品大类有椅子chair和沙发sofa两种
//根据抽象工厂模式的要求,要有抽象产品类及其对应的具体产品类
//所以下面先创建chair和sofa的抽象产品类//抽象椅子类,里面包含生产接口produce()
class Chair{
public:virtual void produce() = 0;
};//具体现代风格椅子类
class ModernChair : public Chair{
public:void produce() override{cout<<"modern chair"<<endl;}
};//具体古典风格椅子类
class ClassicalChair : public Chair{
public:void produce() override{cout<<"classical chair"<<endl;}
};//抽象沙发类
class Sofa{
public:virtual void produce() = 0;
};//具体现代沙发类
class ModernSofa:public Sofa{
public:void produce() override{cout<<"modern sofa"<<endl;}
};//具体古典沙发类
class ClassicalSofa:public Sofa{
public:void produce() override{cout<<"classical sofa"<<endl;}
};//下面是抽象工厂类,声明一组用于创建产品的方法,每个方法对应一种产品
class AbstractFurnitureFactory{
public:virtual Chair* createChair() = 0;virtual Sofa* createSofa() = 0;
};//有了抽象工厂,需要设计具体工厂类,每个类负责生产同一风格的多种不同产品//具体现代风格家具工厂类
class ModernFurnitureFactory:public AbstractFurnitureFactory{
public://生产现代风格的椅子Chair * createChair() override{return new ModernChair();}//生产现代风格的沙发Sofa* createSofa() override{return new ModernSofa();}};//具体古典风格家具工厂类
class ClassicalFurnitureFactory:public AbstractFurnitureFactory{
public://生产古典风格的椅子Chair * createChair() override{return new ClassicalChair();}//生产古典风格的沙发Sofa* createSofa() override{return new ClassicalSofa();}};int main()
{//读取订单数量int N;cin>>N;//处理订单for(int i=0; i<N; ++i){string furnitureType; //准备读取家具类型cin>>furnitureType;//创建相应风格的具体家具工厂AbstractFurnitureFactory * factory = nullptr;if(furnitureType == "modern"){factory = new ModernFurnitureFactory();}else if(furnitureType == "classical"){factory = new ClassicalFurnitureFactory();    }//工厂去生产同风格的多个产品//生产该风格的椅子Chair * chair = factory->createChair();//生产该风格的沙发Sofa * sofa = factory->createSofa();//输出信息chair->produce();sofa->produce();//内存释放delete chair;delete sofa;delete factory;}return 0;
}

简单工厂、工厂模式、抽象工厂模式的区别

  • 简单工厂模式:一个工厂方法创建所有具体产品

  • 工厂方法模式:一个具体工厂方法创建一个具体产品

  • 抽象工厂模式:一个具体工厂方法可以创建一类具体产品

抽象工厂模式应用场景: 

抽象工厂模式能够保证一系列相关的产品一起使用,并且在不修改客户端代码的情况下,可以方便地替换整个产品系列。但是当需要增加新的产品类时,除了要增加新的具体产品类,还需要添加新的抽象工厂接口,修改所有的具体工厂类的生产函数(使其也能够同时生产该类型的新产品),扩展性相对较差。因此抽象工厂模式特别适用于一系列相关或相互依赖的产品被一起创建的情况,典型的应用场景是使用抽象工厂模式来创建与不同数据库的连接对象。

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

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

相关文章

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(1)——场景故事介绍

生成NPC为交互应用程序创建逼真的人类行为模拟。在这项工作中&#xff0c;我们通过将二十五个NPC放置在一个沙盒环境中&#xff08;类似于The Sims&#xff0c;模拟人生&#xff09;&#xff0c;展示了生成NPC的能力。用户可以观察和干预NPC的日常计划、分享新闻、建立关系以及…

就业班 第三阶段(ansible) 2401--4.16 day2 ansible2 剧本+角色

六、Ansible playbook 简介 playbook 是 ansible 用于配置&#xff0c;部署&#xff0c;和管理被控节点的剧本。   通过 playbook 的详细描述&#xff0c;执行其中的一系列 tasks &#xff0c;可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的…

广东海洋大学成功部署(泰迪智能科技)大数据人工智能实验室建设

广东海洋大学简称广东海大&#xff0c;坐落于广东省湛江市&#xff0c;是国家海洋局与广东省人民政府共建的省属重点建设大学、广东省高水平大学重点学科建设高校、粤港澳高校联盟成员 &#xff0c;入选卓越农林人才教育培养计划&#xff0c;是教育部本科教学水平评估优秀院校。…

odoo添加自定义网页---添加模块图标

1.新建一个模块 python odoo-bin scaffold test_web <路径> 2.我们需要修改一下几个文件 3.web.xml <?xml version"1.0" encoding"UTF-8"?> <templates id"template" xml:space"preserve"><t t-name"T…

详解汽车交流充电桩主板的四大版本

近年来&#xff0c;在电动汽车行业快速发展背景下&#xff0c;充电桩的建设变得愈发重要&#xff0c;特别是兼容性较高、适用性较广的交流充电桩。 交流充电桩的心脏——主板的设计与功能&#xff0c;对于充电桩的性能和用户体验起着至关重要的作用。目前&#xff0c;市面上的…

康谋技术 | 深入探讨:自动驾驶中的相机标定技术

随着自动驾驶技术的快速发展&#xff0c;多传感器的数据采集和融合可以显著提高系统的冗余度和容错性&#xff0c;进而保证决策的快速性和正确性。在项目开发迭代过程中&#xff0c;传感器标定扮演着至关重要的角色&#xff0c;它位于数据采集平台与感知融合算法之间&#xff0…

如何使用自定义Promptbooks优化您的安全工作流程

在当今的数字化时代&#xff0c;安全工作流程的优化变得前所未有的重要。安全团队需要快速、有效地响应安全事件&#xff0c;以保护组织的数据和资产。Microsoft Copilot for Security提供了一种强大的工具——自定义Promptbooks&#xff0c;它可以帮助安全专家通过自动化和定制…

tmux 命令速查 导图

最近在使用tmux&#xff0c;整理了一份命令的导图&#xff0c;大家需要自取&#xff5e; tmux是什么&#xff1f; Tmux是一个终端复用器&#xff0c;一个非常有用的linux开发工具。 基本概念 会话&#xff1a; 与命令下的终端窗口类似&#xff1b;tmux进程&#xff0c;可包…

SpringBoot整合Swagger2

SpringBoot整合Swagger2 1.什么是Swagger2&#xff1f;&#xff08;应用场景&#xff09;2.项目中如何使用2.1 导入依赖2.2 编写配置类2.3 注解使用2.3.1 controller注解&#xff1a;2.3.2 方法注解2.3.3 实体类注解2.3.4 方法返回值注解2.3.5 忽略的方法 3.UI界面 1.什么是Swa…

短视频矩阵系统----技术源头开发

短视频矩阵系统--- 1. 确定账号类型和目标受众 2. 准备账号资料 3. 搭建系统框架 4. 开发核心功能 5. 测试和调试 6. 部署和维护 7. 推广和运营 在开发短视频账号矩阵系统源码时&#xff0c;可以使用一些开源框架和工具来提高开发效率和降低开发难度。同时&#xff0c;需要组…

抓取电商产品数据的方法|PHP|Python多语言环境|高并发需求|电商商品API接口数据采集

电商商品数据的抓取|电商平台商品API接口 客户在搭建电商网站时经常提出的诉求和相应的解决方案如下&#xff1a; 1. **网站设计和用户体验**&#xff1a; - 诉求&#xff1a;希望有吸引力、易用性强的网站设计&#xff0c;提升用户体验。 - 解决方案&#xff1a;设计专…

无人机--行业生命周期分析

行业生命周期:无人机行业生命周期还相对较短&#xff0c;但已经经历了多个阶段的发展。从最初的军用无人机&#xff0c;到近年来民用无人机和商业无人机的快速发展&#xff0c;无人机行业正逐渐走向成熟阶段。未来随着技术的不断进步和应用领域的不断拓展&#xff0c;无人机行业…

项目7-音乐播放器5+注册账号

1.前端代码 MAPPER Insert("insert into user(username,password) values (#{username},#{password}) ")Integer insertUserInfo(String username,String password); Service public Result insertUserInfo(String username, String oldpassword,String newpasswo…

如何关掉地址空间随机化

如果我们的ru没有密码的话我们要先建一个密码 接着输入 su 进入root 接着输入 echo 0 > /proc/sys/kernel/randomize_va_space 就可以啦 接着可以cat查看是不是显示0&#xff0c;是的话就成功了

【Linux的git操作】

Linux学习笔记---010 Linux的git操作1、什么是gitee2、git 准备工作2.1、查看是否安装了 git 版本工具2.2、安装 git 工具/更新成最新版本2.3、在gitee上创建远程仓库&#xff08;略&#xff09;2.4、提交file的初始化操作 3、git的“三板斧”3.1、add3.2、commit3.3、push3.4、…

Flutter 像素编辑器#03 | 像素图层

theme: cyanosis 本系列&#xff0c;将通过 Flutter 实现一个全平台的像素编辑器应用。源码见开源项目 【pix_editor】 《Flutter 像素编辑器#01 | 像素网格》《Flutter 像素编辑器#02 | 配置编辑》《Flutter 像素编辑器#03 | 像素图层》 上一篇我们实现了编辑配置&#xff0c;…

React + 项目(从基础到实战) -- 第八期

ajax 请求的搭建 引入mockAP接口设计AJAX 通讯 前置知识 HTTP 协议 , 前后端通讯的桥梁API : XMLHttpRequest 和 fetch常用工具axios mock 引入 Mock.js (mockjs.com) 使用 mockJS 前端代码中引入 mockJs定义要模拟的路由 , 返回结果mockJs 劫持ajax请求(返回模拟的结果)…

2024运营级租房源码管理PHP后台+uniapp前端(app+小程序+H5)

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 房产系统 一款基于ThinkPHPUniapp开发的房产管理系统&#xff0c;支持小程序、H5、APP&#xff1b;包含房客、房东、经纪人三种身份。核心功能有&#xff1a;新盘销售、房屋租赁、地图找房、房源代理、…

RestFul 风格(SpringMVC学习笔记三)

1、什么是Restful风格&#xff1a; Restful就是一个资源定位及资源操作的风格。不是标准也不是协议&#xff0c;只是一种风格。基于这个风格设计的软件可以更简洁&#xff0c;更有层次&#xff0c;更易于实现缓存等机制。 2、使用Restful风格 接上一个笔记的测试类 package…

『Django』创建app(应用程序)

theme: smartblue 本文简介 点赞 关注 收藏 学会了 在《『Django』环境搭建》中介绍了如何搭建 Django 环境&#xff0c;并且创建了一个 Django 项目。 在刚接触 Django 时有2个非常基础的功能是需要了解的&#xff0c;一个是“app”(应用程序)&#xff0c;另一个是 url(路由…