当前位置: 首页 > news >正文

设计模式2、抽象工厂模式 Abstract Factory

解释说明:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
简言之,一个工厂可以提供创建多种相关产品的接口,而无需像工厂方法一样,为每一个产品都提供一个具体工厂
抽象工厂(AbstractFactory):提供了创建抽象的接口,它包含了多个创建产品的方法,可以创建多个不同等级的产品
具体工厂(ConcreteFactory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建
抽象产品(Product):定义产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是一对一的关系
优点
封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。
可以支持不同类型的产品,使得模式灵活性更强。
可以非常方便的使用一族中的不同类型的产品。
缺点:
结构过于臃肿,如果产品类型较多或产品族较多,会非常难于管理。
每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
适用场景
在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
考虑这样一个场景,如下图
Jungle想要进行户外运动,它可以选择打篮球和踢足球。但这次Jungle不想弄脏原本穿的T恤,所以Jungle还需要穿球衣,打篮球就穿篮球衣,踢足球就穿足球衣。篮球保管室可以提供篮球和篮球衣,足球保管室可以提供足球和足球衣。Jungle只要根据心情去某个保管室,就可以换上球衣、拿上球,然后就可以愉快地玩耍了
对应的UML实例图如下图
#pragma once
#include <string>
using namespace std;
// 汽车接口
class ICar
{
public:virtual string Name() = 0;  // 汽车名称
};
/********** 汽车 **********/
// 奔驰
class BenzCar : public ICar
{
public:string Name() {return "Benz Car";}
};
// 宝马
class BmwCar : public ICar
{
public:string Name() {return "Bmw Car";}
};
// 奥迪
class AudiCar : public ICar
{
public:std::string Name() {return "Audi Car";}
};
// 自行车接口
class IBike
{
public:virtual string Name() = 0;  // 自行车名称
};
/********** 自行车 **********/
// 奔驰
class BenzBike : public IBike
{
public:string Name() {return "Benz Bike";}
};
// 宝马
class BmwBike : public IBike
{
public:string Name() {return "Bmw Bike";}
};
// 奥迪
class AudiBike : public IBike
{
public:string Name() {return "Audi Bike";}
};#include "product.h"
// 抽象工厂
class AFactory
{
public:enum FACTORY_TYPE {BENZ_FACTORY,  // 奔驰工厂BMW_FACTORY,  // 宝马工厂AUDI_FACTORY  // 奥迪工厂};virtual ICar* CreateCar() = 0;  // 生产汽车virtual IBike* CreateBike() = 0;    // 生产自行车static AFactory* CreateFactory(FACTORY_TYPE factory);  // 创建工厂
};#include "factory.h"
#include "product.h"
// 奔驰工厂
class BenzFactory : public AFactory
{
public:ICar* CreateCar() {return new BenzCar();}IBike* CreateBike() {return new BenzBike();}
};
// 宝马工厂
class BmwFactory : public AFactory
{
public:ICar* CreateCar() {return new BmwCar();}IBike* CreateBike() {return new BmwBike();}
};
// 奥迪工厂
class AudiFactory : public AFactory
{
public:ICar* CreateCar() {return new AudiCar();}IBike* CreateBike() {return new AudiBike();}
};
// 创建工厂
AFactory* AFactory::CreateFactory(FACTORY_TYPE factory)
{AFactory* pFactory = NULL;switch (factory) {case FACTORY_TYPE::BENZ_FACTORY:  // 奔驰工厂pFactory = new BenzFactory();break;case FACTORY_TYPE::BMW_FACTORY:  // 宝马工厂pFactory = new BmwFactory();break;case FACTORY_TYPE::AUDI_FACTORY:  // 奥迪工厂pFactory = new AudiFactory();break;default:break;}return pFactory;
}#include "factory.h"
#include "product.h"
#include <iostream>
using namespace std;
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif
int main()
{// 奔驰AFactory* pFactory =  AFactory::CreateFactory(AFactory::FACTORY_TYPE::BENZ_FACTORY);ICar* pCar = pFactory->CreateCar();IBike* pBike = pFactory->CreateBike();cout << "Benz factory - Car: " << pCar->Name() << endl;cout << "Benz factory - Bike: " << pBike->Name() << endl;SAFE_DELETE(pCar);SAFE_DELETE(pBike);SAFE_DELETE(pFactory);// 宝马pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::BMW_FACTORY);pCar = pFactory->CreateCar();pBike = pFactory->CreateBike();cout << "Bmw factory - Car: " << pCar->Name() << endl;cout << "Bmw factory - Bike: " << pBike->Name() << endl;SAFE_DELETE(pCar);SAFE_DELETE(pBike);SAFE_DELETE(pFactory);// 奥迪pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::AUDI_FACTORY);pCar = pFactory->CreateCar();pBike = pFactory->CreateBike();cout << "Audi factory - Car: " << pCar->Name() << endl;cout << "Audi factory - Bike: " << pBike->Name() << endl;SAFE_DELETE(pCar);SAFE_DELETE(pBike);SAFE_DELETE(pFactory);getchar();return 0;
}

相关文章:

设计模式2、抽象工厂模式 Abstract Factory

解释说明&#xff1a;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定他们具体的类。 简言之&#xff0c;一个工厂可以提供创建多种相关产品的接口&#xff0c;而无需像工厂方法一样&#xff0c;为每一个产品都提供一个具体工厂 抽象工厂&#xff08;Abstra…...

C++ 32盏灯,利用进制和 与 或 进行设计

一共32盏灯&#xff0c;设计一个灯光控制系统&#xff0c;其中 台球部8盏灯 桌游区8盏灯 酒吧区8盏灯 休息区8盏灯 满足以下功能 1、能够独立控制每一盏灯 2、能够一次性打开或关闭一个区域的全部灯光 3、能够获取各个区域的灯光打开关闭情况 4、能够一次性关闭打开的灯&#x…...

Ffmpeg-(1)-安装:ubuntu系统安装Ffmpeg应用

1、下载源码压缩包 https://ffmpeg.org/download.html 点击Download Source Code下载即可 解压&#xff1a; tar -xvjf ffmpeg-snapshot.tar.bz2 得到&#xff1a;ffmpeg目录 cd ffmpeg 或者&#xff1a;直接下 wget http://www.ffmpeg.org/releases/ffmpeg-5.1.tar.gztar -zx…...

系统集成|第十一章(笔记)

目录 第十一章 项目人力资源管理11.1 项目人力资源管理的定义及有关概念11.2 主要过程11.2.1 编制项目人力资源管理计划11.2.2 组建项目团队11.2.3 建设项目团队11.2.4 管理项目团队 11.3 现代激励理论11.4 项目经理所需具备的影响力11.5 常见问题 上篇&#xff1a;第十章、质量…...

二叉树题目:二叉树剪枝

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉树剪枝 出处&#xff1a;814. 二叉树剪枝 难度 4 级 题目描述 要求 给定二叉树的根结点 root \texttt{root} root&#xff0c;返回移除了所有…...

JAVA中使用CompletableFuture进行异步编程

JAVA中使用CompletableFuture进行异步编程 1、什么是CompletableFuture CompletableFuture 是 JDK8 提供的 Future 增强类&#xff0c;CompletableFuture 异步任务执行线程池&#xff0c;默认是把异步任 务都放在 ForkJoinPool 中执行。 在这种方式中&#xff0c;主线程不会…...

uniapp:配置动态接口域名,根据图片访问速度,选择最快的接口

common.js // 动态测速选择的域名 // h5直接返回默认第一个域名 // vue文件用到域名的话用this.$baseURL let domains [{uri:192.168.31.215:9523, speed:0},{uri:api.ceshi.org, speed:0}, ]export const protocol {api: http://,//本地// api: https://api.,//正式h5Url: h…...

Lambda表达式常见用法(提高效率神器)

Java8中一个非常重要的特性就是Lambda表达式&#xff0c;我们可以把它看成是一种闭包&#xff0c;它允许把函数当做参数来使用&#xff0c;是面向函数式编程的思想&#xff0c;一定程度上可以使代码看起来更加简洁。 其实以上都不重要&#xff0c;重要的是能够提高我的开发效率…...

2023旷视自驾感知算法暑期实习一面

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 1. 问下项目&#xff0c;问下我的情况 2. 是否了解最新的BEV算法&#xff0c;讲一下 3. 是否了解三维重建 4. 考察相机坐标系的转换 5. 手撕代码&#xff0c;翻车了&#xff0c;不考leetcode&#xff0c;考…...

Python3 如何实现 websocket 服务?

Python 实现 websocket 服务很简单&#xff0c;有很多的三方包可以用&#xff0c;我从网上大概找到三种常用的包&#xff1a;websocket、websockets、Flask-Sockets。 但这些包很多都“年久失修”&#xff0c; 比如 websocket 在 2010 年就不维护了。 而 Flask-Sockets 也在 2…...

SQLAlchemy常用数据类型

目录 SQLAlchemy常用数据类型 代码演示 代码分析 SQLAlchemy常用数据类型 SQLAlchemy 是一个Python的SQL工具库和对象关系映射(ORM)工具&#xff0c;它提供了一种在Python中操作数据库的高效方式。下面是SQLAlchemy中常用的一些数据类型&#xff1a; Integer&#xff1a;整形&…...

Vue路由与nodejs下载安装及环境变量的配置

目录 前言 一、Vue路由 1.路由简介 是什么 作用 应用场景 2.SPA简介 SPA是什么 SPA的优点 注意事项 3.路由实现思路 1.引入路由的js依赖 2.定义组件 3.定义组件与路径的对应关系 4.通过路由关系获取路由对象router 5.将路由对象挂载到实例中 6.触发路由事…...

HarmonyOS之 应用程序页面UIAbility

一 UIAbility介绍&#xff1a; 1.1 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互 1.2 UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面 二 UIAbility跳转和传参 2.1 页面间的导航可以通过页面路由router模块来实现。页…...

数据集笔记: Porto

数据来源&#xff1a;Taxi Trajectory Data_数据集-阿里云天池 (aliyun.com) 1 数据介绍 葡萄牙波尔图市运行的所有442辆出租车的全年轨迹&#xff08;从2013年7月1日至2014年6月30日&#xff09; 2 读取数据 import pandas as pdtrapd.read_csv(C:/Users/16000/Download…...

修改vscode底部栏背景和字体颜色

修改vscode底部栏背景和字体颜色 如图&#xff1a; 首先打开齿轮&#xff0c;打开设置搜索workbench.colorCustomizations,然后点击编辑setting.json修改setting.json内内容 "workbench.colorCustomizations": {"statusBar.foreground": "#FFFFFF…...

加速企业AI实施:成功策略和效率方法

文章目录 写在前面面临的挑战MlOps简介好书推荐 写作末尾 写在前面 作为计算机科学领域的一个关键分支&#xff0c;机器学习在当今人工智能领域中占据着至关重要的地位&#xff0c;广受瞩目。机器学习通过深入分析大规模数据并总结其中的规律&#xff0c;为我们提供了解决许多…...

【图论C++】树的重心——教父POJ 3107(链式前向星的使用)

》》》算法竞赛 /*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在竞赛算法学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记&#xff1a;转载…...

hhh百度地铁广告太搞笑了;24家国内大模型公司面经;LLM法律应用实践;AI+教育产品图谱与工作流 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 会玩儿&#xff01;承包地铁专列&#xff0c;真人移动广告 | 百度世界大会预热 百度也是会玩儿&#xff01;承包了北京地铁一号线的「…...

项目管理:项目经理一定要避开这四大误区

项目经理要保质保量按时达成项目目标&#xff0c;需要关注项目的方方面面&#xff0c;要具有很强的沟通协调能力和目标意识。但是项目经理也不免不了失误&#xff0c;管理中的这四大误区&#xff0c;你经历过几个&#xff1f; 误区一&#xff1a;做不该做的事 你是否遇到这种…...

爬虫为什么需要 HTTP 代理 IP?

前言 爬虫在互联网数据采集、分析和挖掘中扮演着至关重要的角色&#xff0c;但是对于目标网站而言&#xff0c;频繁的爬虫请求可能会对其服务器产生不小的负担&#xff0c;严重的情况甚至会导致网站崩溃或者访问受限。为了避免这种情况的发生&#xff0c;同时也为了保护客户端…...

Simulink Assignment模块实战:如何像写C代码一样更新数组元素?

Simulink Assignment模块实战&#xff1a;从C语言思维到模型化设计的无缝衔接 对于习惯用C语言编写控制算法的工程师来说&#xff0c;第一次接触Simulink的模块化设计往往会感到不适应——尤其是当需要更新数组中的特定元素时。在C语言中&#xff0c;我们只需简单地写下array[2…...

3步掌握微信聊天记录导出:永久保存你的数字记忆

3步掌握微信聊天记录导出&#xff1a;永久保存你的数字记忆 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否担心手机丢失或更换时&#xff0c;珍贵的微信聊天记录会…...

量子网络模拟器SeQUeNCe的并行化设计与性能优化

1. 量子网络模拟的工程挑战与SeQUeNCe的定位量子网络正逐步从理论走向工程实践&#xff0c;其核心价值在于利用量子纠缠特性实现传统通信无法企及的安全性和计算能力。但在实际部署前&#xff0c;工程师们面临一个关键问题&#xff1a;如何验证包含数百个量子节点的网络设计方案…...

基于RAG架构的本地知识库构建:从原理到Shannon实战

1. 项目概述&#xff1a;一个面向开发者的高效本地知识库构建工具最近在折腾个人知识管理和团队文档沉淀时&#xff0c;发现了一个挺有意思的开源项目&#xff0c;叫Shannon。这项目名挺有深意&#xff0c;取自信息论之父克劳德香农&#xff0c;一听就知道是跟信息处理和知识组…...

使用Hermes Agent框架时接入Taotoken自定义供应商的步骤详解

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Hermes Agent框架时接入Taotoken自定义供应商的步骤详解 对于使用Hermes Agent框架的开发者而言&#xff0c;将后端AI服务接入…...

React Hook useVibe:声明式时序管理与交互感知的工程实践

1. 项目概述&#xff1a;一个能“感知”用户意图的React Hook 最近在做一个需要深度交互的前端项目&#xff0c;遇到了一个挺有意思的痛点&#xff1a;如何让UI组件不只是被动地响应事件&#xff0c;而是能更“聪明”地理解用户的交互意图&#xff0c;甚至预判下一步操作&#…...

ARM架构SUB与SUBS减法指令详解

1. ARM减法指令概述在ARM架构中&#xff0c;SUB&#xff08;减法&#xff09;和SUBS&#xff08;带标志位的减法&#xff09;是最基础的算术指令之一。这些指令用于执行寄存器值的减法操作&#xff0c;是构建更复杂算术运算和控制流程的基础。SUB指令从目标寄存器中减去一个立即…...

Syzygy-of-Thoughts:用代数几何思想提升大语言模型推理能力

1. 项目概述&#xff1a;当大语言模型遇上代数几何如果你最近在折腾大语言模型&#xff08;LLM&#xff09;的推理能力提升&#xff0c;大概率听说过“思维链”&#xff08;Chain of Thought, CoT&#xff09;和“自洽性”&#xff08;Self-Consistency, CoT-SC&#xff09;这些…...

Cursor Pro破解工具:简单5步实现AI编程助手永久免费使用

Cursor Pro破解工具&#xff1a;简单5步实现AI编程助手永久免费使用 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your t…...

数据中心48V直连供电架构:从效率瓶颈到硬件设计实战

1. 数据中心供电演进&#xff1a;从香农理论到48V直连架构1948年&#xff0c;克劳德香农发表《通信的数学理论》&#xff0c;用1和0的二进制语言为信息时代奠基。六十八年后的今天&#xff0c;当我们谈论数据中心——这个承载着全球信息洪流的数字心脏时&#xff0c;讨论的焦点…...