设计模式(二)-创建者模式(3)-抽象工厂模式
一、为什么需要抽象工厂模式?
在工厂模式中,我们需要定义多个继承于共同工厂抽象基类的工厂子类,这些子类负责创建一个对应的对象。工厂模式存在一个缺点就是:每次扩展新的工厂子类,就会增加系统的复杂度。
如果我们知道把所有产品(比如车)分为几个产品族(比如自行车族、汽车族),那么工厂子类就对应指定的产品族进行“批量”创建对象。若有新的产品,则工厂子类创建该新产品对象。(工厂子类内部逻辑,类似于简单工厂模式)
抽象工厂模式 ,类似于简单工厂模式和工厂模式混合运用而成的模式。(参考上篇文章“工厂模式”的最后一个代码例子)
优点: 不需要每次定义一个新的产品类时,就要扩展新的工厂子类。工厂子类提供一个产品族中多个对象的创建工作,客户端可以方便使用某个产品族中的对象。
缺点: 产品族扩展难。要增加一个新系列的某一产品,要定义产品抽象类、产品实现类,工厂抽象基类,工厂子类。
【角色】
某系列抽象基类: 用以定义某产品族的特征和行为的抽象接口。
某系列的某产品实现类: 继承某系列抽象基类,用以实现某系列里某产品的特征和行为的具体类。
工厂抽象基类: 用以定义创建对象的特征的抽象接口。特征行为包括提供某系列产品的抽象方法。
工厂子类: 对对应的实现类进行实例化。实现提供某系列某产品的方法。
二、例子
需求: 假定某些地方的主要交通工具有自行车和汽车。为了满足人们交通便利的需求,现有XX公司和YY公司这两家公司,对市场推行了两种运营模式:租车和共享车。也就是说,租车和共享车是这两家公司所推广的两个产品系列业务,即两个产品族。
1)定义产品族和具体产品
//共享车系列(产品族)public abstract class Share{public abstract void Move();}//租借车系列public abstract class Rent{public abstract void Move();}//XX公司-共享-自行车public class XXBikeShare : Share{public override void Move(){Console.WriteLine("Share XXBike move.");}}//XX公司-共享-汽车public class XXCarShare : Share{public override void Move(){Console.WriteLine("share XXCar move.");}}//XX公司-租借-自行车public class XXBikeRent : Rent{public override void Move(){Console.WriteLine("Rent XXBike move.");}}//XX公司-租借-汽车public class XXCarRent : Rent{public override void Move(){Console.WriteLine("Rent XXCar move.");}}//YY公司-共享-自行车public class YYBikeShare : Share{public override void Move() {Console.WriteLine("share YYBike move.");}}//YY公司-共享-汽车public class YYCarShare : Share{public override void Move() {Console.WriteLine("share YYCar move.");}}//YY公司-租借-自行车public class YYBikeRent : Rent{public override void Move(){Console.WriteLine("Rent YYBike move.");}}//YY公司-租借-汽车public class YYCarRent : Rent{public override void Move(){Console.WriteLine("Rent YYCar move.");}}
2)定义工厂基类和工厂子类
//定义提供两个产品族的抽象方法public abstract class Factory{public abstract Share ProvideS(string args);public abstract Rent ProvideR(string args);}//XX公司落实产品业务:租借和共享public class XXFactory : Factory{public override Share ProvideS(string args){Share share = null;switch (args){case "XXBike":share = new XXBikeShare(); break;case "XXCar":share = new XXCarShare(); break;default:throw new ArgumentException("args is Invalid. new obj failed.");}return share;}public override Rent ProvideR(string args){Rent rent = null;switch (args){case "XXBike":rent = new XXCarRent(); break;case "XXCar":rent = new XXBikeRent(); break;default:throw new ArgumentException("args is Invalid. new obj failed.");}return rent;}}//YY公司落实产品业务:租借和共享public class YYFactory : Factory{public override Share ProvideS(string args){Share share = null;switch (args){case "YYBike":share = new YYBikeShare(); break;case "YYCar":share = new YYCarShare(); break;default:throw new ArgumentException("args is Invalid. new obj failed.");}return share;}public override Rent ProvideR(string args){Rent rent = null;switch (args){case "YYBike":rent = new YYBikeRent(); break;case "YYCar":rent = new YYCarRent(); break;default:throw new ArgumentException("args is Invalid. new obj failed.");}return rent;}}
3)在客户端使用
class Program{static void Main(string[] args){Factory xx = new XXFactory();Factory yy = new YYFactory();var sharexxCar = xx.ProvideS("XXCar");sharexxCar.Move();var rentyyBike = yy.ProvideR("YYBike");rentyyBike.Move();Console.ReadLine();}}
相关文章:

设计模式(二)-创建者模式(3)-抽象工厂模式
一、为什么需要抽象工厂模式? 在工厂模式中,我们需要定义多个继承于共同工厂抽象基类的工厂子类,这些子类负责创建一个对应的对象。工厂模式存在一个缺点就是:每次扩展新的工厂子类,就会增加系统的复杂度。 如果我们…...

[计算机网络]网络层概述
呼,写了这么久终于重新开始啦! 自己落下了太多东西了.....是时候应该重新拾掇起来了. 关于后面的代码项目,我的想法是vilas.js仍然使用js来进行编写,但是后续其他的项目会开始尝试使用ts来进行书写了. 就算是前端也需要点规范吧..... 0.写在前面 这篇文章要和大家道个歉,首…...

猫12分类:使用yolov5训练检测模型
前言: 在使用yolov5之前,尝试过到百度飞桨平台(小白不建议)、AutoDL平台(这个比较友好,经济实惠)训练模型。但还是没有本地训练模型来的舒服。因此远程了一台学校电脑来搭建自己的检测模型。配置…...

Kubernetes Dashboard部署ImagePullBackOff问题处理
通常,出现ImagePullBackOff问题是由于Kubernetes集群无法拉取所需的镜像导致的。解决这个问题的方法通常包括以下步骤: 1. 检查Pod的描述信息: kubectl describe pod/[pod名称] --namespacekubernetes-dashboard 查看Events部分是否有关于…...

十四、Docker的基本操作
目录 (一)镜像命令 一、拉取Nginx 二、查看镜像 三、导出文件 四、删除镜像 五、加载镜像 (二)容器命令 一、例子:运行一个nginx容器 1、输入运行命令 2、使用命令查看宿主机ip 3、在外部浏览器访问 4、查看…...

C#,数值计算——插值和外推,分段线性插值(Linear_interp)的计算方法与源程序
1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 分段线性插值 /// Piecewise linear interpolation object. /// Construct with x and y vectors, then call interp for interpolated values. /// </summary> …...
详细讲解什么是单例模式
当谈到单例模式时,我们指的是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式在软件开发中很常见,特别是需要控制资源访问、配置管理、日志记录器等情况下。 让我们用一个简单的例子来解释单…...
在springBoot中同时使用mysql和MongoDB
在SpringBoot中非关系向数据库MongoDB和关系型数据库MySQL都可通过引入相关依赖并按照指定配置单独集成; mysql引入依赖: compile "org.springframework.boot:spring-boot-starter-web:1.5.18.RELEASE"compile "org.springframework.boot:spring-boot-start…...

2023.11.19 hadoop之MapReduce
目录 1.简介 2.分布式计算框架-Map Reduce 3.mapreduce的步骤 4.MapReduce底层原理 map阶段 shuffle阶段 reduce阶段 1.简介 Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于hadoop的数据分析应用”的核心框架; Mapreduce核心功能是…...
力扣第841题 钥匙和房间 C++ DFS BFS 附Java代码
题目 841. 钥匙和房间 中等 相关标签 深度优先搜索 广度优先搜索 图 有 n 个房间,房间按从 0 到 n - 1 编号。最初,除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而,你不能在没有获得钥匙的时候进入锁住的房间…...

React 中 react-i18next 切换语言( 项目国际化 )
背景 平时中会遇到需求,就是切换语言,语种等。其实总的来说都是用i18n来实现的 思路 首先在项目中安装i18n插件,然后将插件引入到项目,然后配置语言包(语言包需要你自己来进行配置,自己编写语言包ÿ…...
antd design 5 版本 文件上传
<UploadcustomRequest{customRequest}accept".csv" showUploadList{false}><Button icon{<UploadOutlined />}>上传 CSV 文件</Button></Upload> accept 代表限制的上传类型 也可设置 .excel // 文件上传 ( CSV ) const customReques…...
【如何学习Python自动化测试】—— 浏览器操作
4 、 浏览器操作 4.1 浏览器最大化 Webdriver 打开浏览器后,默认不是最大化,如果需要界面最大化,需要通过 maximize_window()方法来实现,代码如下: maximize_window()方法是Selenium WebDriver提供的一个方法…...

Python编程技巧 – 使用字典
Python编程技巧 – 使用字典 Python Programming Skills – Using Dictionary Dictionary, 即字典,这是Python语言的一种重要的数据结构;Python字典是以键(key)值(value)对为元素,来存储数据的集合。 前文提到Python列…...

el-tree 与table表格联动
html部分 <div class"org-left"><el-input v-model"filterText" placeholder"" size"default" /><el-tree ref"treeRef" class"filter-tree" :data"treeData" :props"defaultProp…...

Leetcode刷题详解——删除并获得点数
1. 题目链接:740. 删除并获得点数 2. 题目描述: 给你一个整数数组 nums ,你可以对它进行一些操作。 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] …...

HTTP四种请求方式,状态码,请求和响应报文
1.get请求 一般用于获取数据请求参数在URL后面请求参数的大小有限制 2.post请求 一般用于修改数据提交的数据在请求体中提交数据的大小没有限制 3.put请求 一般用于添加数据 4.delete请求 一般用于删除数据 5.一次完整的http请求过程 域名解析:使用DNS协议…...

Python - Wave2lip 环境配置与 Wave2lip x GFP-GAN 实战 [超详细!]
一.引言 前面介绍了 GFP-GAN 的原理与应用,其用于优化图像画质。本文关注另外一个相关的项目 Wave2lip,其可以通过人物视频与自定义音频进行适配,改变视频中人物的嘴型与音频对应。 二.Wave2Lip 简介 Wave2lip 研究 lip-syncing 以达到视频…...
2311rust,1.31版本更新
1.31.0稳定版 Rust1.31可能是最激动人心的版本! 使用Cargo创建一个新项目: cargo new foo以下是Cargo.toml的内容: [package] name "foo" version "0.1.0" authors ["名字"] edition "2018" //版本. [dependencies]在[package]…...

文心一言-情感关怀之旅
如何让LLM更有温度。 应用介绍...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...