设计模式12:抽象工厂模式
系列总链接:《大话设计模式》学习记录_net 大话设计-CSDN博客
参考:
C++设计模式:抽象工厂模式(风格切换案例)_c++ 抽象工厂-CSDN博客
1.概念
抽象工厂模式(Abstract Factory Pattern)是软件设计模式中的一种创建型模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这种模式强调的是家族的概念,即一个工厂可以生产出一整套兼容的产品。
2.结构与实现
结构:
- 抽象工厂 (Abstract Factory)
定义了一个创建一组相关或相互依赖对象的接口,但不负责这些对象的具体类。它声明了一组用于创建不同产品的方法,但并不实现它们。
- 具体工厂 (Concrete Factory)
实现了抽象工厂接口,负责创建具体的产品对象。每个具体工厂对应一个特定的产品族,并能够创建该族中的所有产品。
- 抽象产品 (Abstract Product)
为每类产品定义了一个接口,具体产品的类实现这个接口。不同的产品族可能有不同的抽象产品接口。
- 具体产品 (Concrete Product)
由具体工厂创建的对象,实现了抽象产品接口。每个具体产品属于一个特定的产品族,并且与同一族中的其他产品兼容。
- 客户端代码 (Client Code)
客户端代码使用抽象工厂和抽象产品接口来操作对象,而不直接引用具体工厂或具体产品的类。这使得客户端代码可以独立于具体的产品实现。
通过上述结构,抽象工厂模式提供了一种方式来创建一系列相关的对象,而无需指定它们的具体类。这种方式不仅提高了代码的灵活性和可维护性,还使得添加新的产品族变得更为简单,因为只需要增加一个新的具体工厂和相应的产品实现即可。
实现:
#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H//抽象产品类
class IProductPhone
{
public:IProductPhone() {}virtual void showPhoneType(){}
};//具体产品类
class Piphone : public IProductPhone
{
public:Piphone() {}void showPhoneType(){qDebug() << "i am iphone";}
};class PXiaomi : public IProductPhone
{
public:PXiaomi() {}void showPhoneType(){qDebug() << "i am xiaomi";}
};//抽象工厂类
class IFactory
{
public:IFactory() {}virtual IProductPhone* createPhone(){}
};//具体工厂类
class IphoneFactory : public IFactory
{
public:IphoneFactory(){}IProductPhone* createPhone(){qDebug() << "create a iphone"; return new Piphone;}
};class XiaomiFactory : public IFactory
{
public:XiaomiFactory(){}IProductPhone* createPhone(){qDebug() << "create a xiaomi"; return new PXiaomi;}
};#endif // ABSTRACTFACTORY_H
使用:
#include <QCoreApplication>
#include <QDebug>#include "abstractFactory.h"int main(int argc, char *argv[])
{IFactory* ifact=nullptr;IProductPhone* iprod = nullptr;QString currentFact = "xiaomi";if("xiaomi" == currentFact){ifact = new XiaomiFactory;}else if("iphone" == currentFact){ifact = new IphoneFactory;}iprod = ifact->createPhone();iprod->showPhoneType();return 0;
}
3.应用
-
数据库访问层(DAL)
当应用程序需要支持多种数据库后端时,可以为每种数据库类型定义一个工厂,用于创建相应的数据访问对象(DAO)。这样可以轻松切换数据库而无需修改业务逻辑代码。如:
MySQLFactory
创建适用于 MySQL 数据库的数据访问对象。OracleFactory
创建适用于 Oracle 数据库的数据访问对象。
4.优缺点及适用环境
优点:
- 将客户端代码与具体的产品实现解耦:
客户端只需要依赖于抽象接口,而不需要知道具体的类。这提高了代码的灵活性和可维护性。
- 易于添加新的产品族:
只需创建一个新的具体工厂和相关的产品实现,即可扩展系统支持新的产品族,符合“开闭原则”。
- 确保同一产品族的产品一起使用:
确保从同一个工厂创建的产品是兼容的,避免了不同产品族之间的不一致问题。
- 简化了复杂的对象创建逻辑:
将对象创建逻辑集中到工厂中,使得客户端代码更加简洁,减少了重复代码。
缺点:
- 增加了系统的复杂度:
引入了额外的接口和类,可能会使系统更难理解,特别是对于小型项目或简单需求来说。
- 难以添加新产品:
如果需要添加一个新的产品类型(而不是新的产品族),则必须修改所有工厂类,违反了“开闭原则”。
- 可能导致过度设计:
在一些场景下,可能没有必要引入这么复杂的模式,导致设计过于复杂,增加不必要的开发和维护成本。
适用环境:
- 当系统需要独立于其产品的创建、组合和表示时:
特别是当你希望提供一个框架或库,但不想暴露内部的具体实现细节。
- 当一个系统要由多个产品系列中的一个来配置时:
比如多平台UI库、多数据库后端的支持等,每个系列有自己的一组相关联的对象。
- 当系统需要支持插件或模块化扩展时:
插件可以提供自己的工厂实现,以创建特定功能和服务,而不影响核心系统。
- 当需要频繁切换不同产品族时:
例如,在运行时根据用户选择或其他条件动态地改变产品族。
总结来说,抽象工厂模式非常适合那些需要处理多个产品系列的应用程序,并且这些系列中的对象需要保持一致性。它有助于提高代码的灵活性和可维护性,但也可能带来额外的复杂性和设计上的挑战。在决定是否采用此模式时,应权衡项目的实际需求和复杂度。
相关文章:
设计模式12:抽象工厂模式
系列总链接:《大话设计模式》学习记录_net 大话设计-CSDN博客 参考: C设计模式:抽象工厂模式(风格切换案例)_c 抽象工厂-CSDN博客 1.概念 抽象工厂模式(Abstract Factory Pattern)是软件设计…...

论文学习——多种变化环境下基于多种群进化的动态约束多目标优化
论文题目:Multipopulation Evolution-Based Dynamic Constrained Multiobjective Optimization Under Diverse Changing Environments 多种变化环境下基于多种群进化的动态约束多目标优化(Qingda Chen , Member, IEEE, Jinliang Ding , Senior Member, …...

Jenkins参数化构建详解(This project is parameterized)
本文详细介绍了Jenkins中不同类型的参数化构建方法,包括字符串、选项、多行文本、布尔值和git分支参数的配置,以及如何使用ActiveChoiceParameter实现动态获取参数选项。通过示例展示了传统方法和声明式pipeline的语法 文章目录 1. Jenkins的参数化构建1…...

Cerebras 推出 CePO,填补推理与规划能力的关键空白
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
广东省食品销售中高级题库及答案
1.有关食品安全标准的说法正确的是(C)。 A.鼓励性标准 B.推荐性标准 C.强制性标准 D.引导性标准 2.食品经营许可证载明的许可事项发生变化的,食品经营者应当在变化后(D)个工作日内向原发证的食品药品监督管理部门申请变更经营许可。 A.3 B.5 C.7 D.10 3.食品销售经营者对食品…...

JAVA基础-深入理解Java内存模型(一)-- 重排序与先行发生原则(happens-before)
深入理解Java内存模型(一)-- 重排序 很棒的一个关于Java内存模型系列文章,首先感谢作者,转载自深入理解java内存模型系列文章 ,为了方便阅读,做了一些内容整合和重排版。 提纲 Java线程之间的通信对程序…...

【Lambda】java之lambda表达式stream流式编程操作集合
java之lambda表达式&stream流式编程操作集合 1 stream流概念1.1 中间操作1.1.1 无状态操作1.1.2 有状态操作 1.2 终端操作1.2.1 非短路操作1.2.2 短路操作 2 steam流的生成2.1 方式一:数组转为stream流2.2 方式二:集合转为steam流2.3 方式三…...

家具购物小程序+php
基于微信小程序的家具购物小程序的设计与实现 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了基于微信小程序的家具购物小程序的设计与实现的开发全过程。通过分析基于微信小程序的家具购物小程序的设计与实…...

【GIS教程】使用GDAL-Python将tif转为COG并在ArcGIS Js前端加载-附完整代码
目录 一、数据格式 二、COG特点 三、使用GDAL生成COG格式的数据 四、使用ArcGIS Maps SDK for JavaScript加载COG格式数据 一、数据格式 COG(Cloud optimized GeoTIFF)是一种GeoTiff格式的数据。托管在 HTTP 文件服务器上,可以代替geose…...
VB.net进行CAD二次开发(二)与cad交互
开发过程遇到了一个问题:自制窗口与控件与CAD的交互。 启动类,调用非模式窗口 Imports Autodesk.AutoCAD.Runtime Public Class Class1 //CAD启动界面 <CommandMethod("US")> Public Sub UiStart() Dim myfrom As Form1 New…...
【NLP 11、Adam优化器】
祝你先于春天, 翻过此间铮铮山峦 —— 24.12.8 一、Adam优化器的基本概念 定义 Adam(Adaptive Moment Estimation)是一种基于梯度的优化算法,用于更新神经网络等机器学习模型中的参数。它结合了动量法(Momentum&…...

51单片机应用开发(进阶)---串口接收字符命令
实现目标 1、巩固UART知识; 2、掌握串口接收字符数据; 3、具体实现目标:(1)上位机串口助手发送多字符命令,单片机接收命令作相应的处理(如:openled1 即打开LED1;closeled1 即关…...
redis 怎么样删除list
在 Redis 中,可以使用以下方法删除列表或列表中的元素: 1. 删除整个列表 使用 DEL 命令删除一个列表键: DEL mylist这个命令会删除键 mylist 及其值(无论 mylist 是一个列表还是其他类型的键)。 2. 删除列表中的部分…...

【数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
目录😋 任务描述 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现快速排序算法。 测试说明 平台会对你编写的代码进行测试: 测试输入示例: 10 6 8 7 9 0 1 3 2 4 5 (说明:第一行是元素个数&a…...

npm或yarn包配置地址源
三种方法 1.配置.npmrc 文件 在更目录新增.npmrc文件 然后写入需要访问的包的地址 2.直接yarn.lock文件里面修改地址 简单粗暴 3.yarn install 的时候添加参数 设置包的仓库地址 yarn config set registry https://registry.yarnpkg.com 安装:yarn install 注意…...
STUN服务器用于内网NAT的方案
在内网中部署 STUN 服务器的场景通常用于处理多层 NAT 或内网客户端之间的通信需求,尤其是在大企业或学校等复杂网络环境下。通过 STUN 服务器,可以帮助客户端设备检测和适配 NAT 转换规则,进而支持 WebRTC 或其他实时通信技术的正常运行。 …...

Linux 简单命令总结
1. 简单命令 1.1. ls 列出该目录下的所有子目录与文件,后面还可以跟上一些选项 常用选项: ・-a 列出目录下的所有文件,包括以。开头的隐含文件。 ・-d 将目录象文件一样显示,而不是显示其下的文件。如:ls -d 指定目…...
Vue.js组件开发:提升你的前端工程能力
Vue.js 是一个用于构建用户界面的渐进式框架,它允许开发者通过组件化的方式创建可复用且易于管理的代码。在 Vue.js 中开发组件是一个直观且高效的过程,下面我将概述如何创建和使用 Vue 组件,并提供一些最佳实践。 1. 创建基本组件 首先&am…...
使用 Pandas 读取 JSON 数据的五种常见结构解析
文章目录 引言JSON 数据的五种常见结构1. split 结构2. records 结构3. index 结构4. columns 结构5. values 结构 引言 在日常生活中,我们经常与各种数据打交道,无论是从网上购物的订单信息到社交媒体上的动态更新。JSON(JavaScript Object…...

C++鼠标轨迹算法(鼠标轨迹模拟真人移动)
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...