c#设计模式-创建型模式 之 工厂模式
前言:
工厂模式(Factory Pattern)是一种常用的对象创建型设计模式。该模式的主要思想是提供一个创建对象的接口(也可以是抽象类、静态方法等),将实际创建对象的工作推迟到子类中进行。这样一来,客户端只需关注接口而无须了解具体的类实现,实现了代码的解耦,提高了系统的可维护性和扩展性。
工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式。
-
简单工厂模式:又叫静态工厂方法模式,它是由一个工厂对象决定创建出哪一种产品类的实例,但它不属于工厂模式家族,它属于创建型模式,但不属于23种GOF设计模式之一。
-
工厂方法模式:提供了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让类把实例化推迟到子类。
-
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。
简单工厂模式
简单工厂模式主要由三个部分组成:
- 工厂角色(Factory):负责实现创建所有实例的内部逻辑
- 抽象产品角色(Product Interface):是工厂类所创建所有对象的父类,封装了各种产品对象的公有方法
- 具体产品角色(ConcreteProduct):它是抽象产品角色的一个或多个具体角色,完成具体产品的创建
简单工厂模式适合于产品数量较少且稳定,客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心的情况。如果产品数量较多且经常变动,使用简单工厂可能会导致工厂方法内部过于复杂,不便于管理和维护。
抽象产品角色
创建一个动物接口,有一个方法speak
public interface IAinimal
{void Speak();
}
具体产品角色
创建两个实现了IAnimal接口的类,分别是Dog和Cat
public class dog : IAinimal
{public void Speak(){Console.WriteLine("汪汪汪");}
}public class cat : IAinimal
{public void Speak(){Console.WriteLine("喵喵喵");}
}
工厂角色
创建一个简单工厂类SimpleAinimalFactory,里面有一个静态方法CreateAinimal,该方法接收一个字符串参数,根据参数创建不同的对象
public static class SimpleAinimalFactory
{public static IAinimal CreateAinimal(string type){if ("cat".Equals(type)){return new cat();}else if ("dog".Equals(type)){return new dog();}else{throw new Exception("Invalid animal type");}}
}
使用简单工厂
public static void Main(string[] args){IAinimal dog = SimpleAinimalFactory.CreateAinimal("dog");dog.Speak();IAinimal cat = SimpleAinimalFactory.CreateAinimal("cat");cat.Speak();}

后期如果再加新的动物,我们势必要需求修改SimpleAinimalFactory的代码,违反了开闭原则。
工厂方法模式
针对上例中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则。
工厂方法模式的主要角色:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂 方法来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同 具体工厂之间一一对应。
抽象产品和具体产品同上不变,将工厂角色抽出来,改成抽象工厂+具体工厂
抽象工厂
public interface IAinimalFactory
{IAinimal createAinimal();
}
具体工厂
public class CatAinimalFactory : IAinimalFactory
{public IAinimal createAinimal(){return new cat();}
}public class DogAinimalFactory : IAinimalFactory
{public IAinimal createAinimal(){return new dog();}
}
使用工厂
public static void Main(string[] args){var catAinimalFactory = new CatAinimalFactory();var ainimal = catAinimalFactory.createAinimal();ainimal.Speak();}
与简单工厂不同的地方就是这边先获取一个对应的具体工厂,再通过具体工厂拿到具体产品。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。
相关文章:
c#设计模式-创建型模式 之 工厂模式
前言: 工厂模式(Factory Pattern)是一种常用的对象创建型设计模式。该模式的主要思想是提供一个创建对象的接口(也可以是抽象类、静态方法等),将实际创建对象的工作推迟到子类中进行。这样一来,…...
Photoshop 2023 25.0beta「Mac」
Photoshop 2023是一款专业图像处理软件,它主要用于图像编辑、合成和设计等方面。 Photoshop beta创新式填充的功能特色包括: 自动识别和删除对象:该功能可以自动识别图像中的对象,并用周围的图像填充空白部分,使图像看…...
机器学习基础07-模型选择01-利用scikit-learn 基于Pima 数据集对LogisticRegression算法进行评估
选择合适的模型是机器学习和深度学习中非常重要的一步,它直接影响到模型的性能和泛化能力。 “所有模型都是坏的,但有些模型是有用的”。建立模型之后就要去评 估模型,确定模型是否有用。模型评估是模型开发过程中不可或缺的一部 分ÿ…...
单片机实现动态内存管理
1.简介 多数传统的单片机并没有动态内存管理功能。单片机通常具有有限的存储资源,包括固定大小的静态RAM(SRAM)用于数据存储和寄存器用于特定功能。这些资源在编译时被分配并且在程序的整个生命周期中保持不变。 2.动态内存管理好处 灵活性和…...
(JS逆向专栏十一)某融平台网站登入RSA
声明: 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 名称:点融 目标:登入参数 加密类型:RSA 目标网址:https://www.dianrong.com/accoun…...
c++ boost circular_buffer
boost库中的 circular_buffer顾名思义是一个循环缓冲器,其 capcity是固定的当容量满了以后,插入一个元素时,会在容器的开头或结尾处删除一个元素。 circular_buffer为了效率考虑,使用了连续内存块保存元素 使用固定内存&#x…...
网络编程——端口
端口 一、端口概述 TCP/IP 协议采用端口标识通信的进程 用于区分一个系统里的多个进程 二、端口特点 1、对于同一个端口,在本同系统中对应着不同的进程 2、对于同一个系统,一个端口只能被一个进程拥有 3、一个进程拥有一个端口后,传输层送…...
【网络】自定义协议 | 序列化和反序列化 | Jsoncpp
本文首发于 慕雪的寒舍 以tcpServer的计算器服务为例,实现用jsoncpp来进行序列化和反序列化 阅读本文之前,请先阅读 自定义协议 | 序列化和反序列化 | 以tcpServer为例 1.安装jsoncpp 我所用的系统是centos7.6,先用下面的命令查找相关的包 …...
PHP实践:用openssl打造安全可靠的API签名验证系统
🏆作者简介,黑夜开发者,全栈领域新星创作者✌,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已…...
每天一道leetcode:剑指 Offer 50. 第一个只出现一次的字符(适合初学者)
今日份题目: 在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 示例1 输入:s "abaccdeff" 输出:b 示例2 输入:s "" 输出: 提示 0 …...
【第五章 flutter学习之flutter进阶组件-下篇】
文章目录 一、Scaffold属性二、TabBar三、路由四、AlertDialog、SimpleDialog、showM...五、PageView六、Key七、AnimatedList八、动画 一、Scaffold属性 Flutter Scaffold 是一个用于构建基本用户界面的布局组件。它提供了许多属性,使得开发者能够轻松地创建一个完…...
单元测试和集成测试有什么区别
单元测试和集成测试有什么区别 单元测试和集成测试是软件开发中的两个重要测试阶段,它们的主要区别如下: 目的: 单元测试:主要针对代码的最小可测试单元,通常是一个函数或方法,确保它按照预期工作。集成…...
如何实现基于场景的接口自动化测试用例?
自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。 基于这个想法,我们的接口自动化测试思路如下…...
SAP 开发编辑界面-关闭助手
打开关闭助手时的开发界面如下: 关闭关闭助手后的界面如下: 菜单栏: 编辑--》修改操作--》关闭助手...
【el-image图片查看时 样式穿透表格问题】
element-ui el-image图片查看 样式混乱 解决方式 ::v-deep(.el-table__cell) {position: static !important; // 解决el-image 和 el-table冲突层级冲突问题 }加个样式即可...
GPT带我学-设计模式-模板模式
1 请你给我介绍一下设计模式中的模板模式 模板模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。模板模式允许子类重新定义算法的某些特定步骤,而不需要改变算法的结构。 模板模式由以下几个角色组成&…...
Windows下调试UEFI程序:Visual Studio调试
以edk2\MdeModulePkg\Application\HelloWorld这个项目作为调试目标。 1. 使用VS2017建立Makefile工程 VS2017, 新建 project,取名X64dbg_vs。 Visual C > Other > Makefile Project, 注意项目路径为HelloWord程序路径。 随便填写config中的字符串ÿ…...
Vue中监听路由参数变化的几种方式
目录 一. 路由监听方式: 通过 watch 进行监听 1. 监听路由从哪儿来到哪儿去 2. 监听路由变化获取新老路由信息 3. 监听路由变化触发方法 4. 监听路由的 path 变化 5. 监听路由的 path 变化, 使用handler函数 6. 监听路由的 path 变化,触发method…...
angular——子组件如何接收父组件的动态传值
开发过程中,父组件给子组件传值的情况很常见,今天我们就来聊聊父组件给子组件传值可能会发生哪些意外,什么情况下子组件无法接收到父组件最新的传值; 传值情况: 基本数据类型:父组件给子组件传递 基本数据…...
php 桥接模式
一,桥接模式,是结构设计模式的一种,其将抽象部分和实现部分分离开来,使两部分可以独立的进行修改,提高系统的灵活性。在桥接模式中,需要定义一个抽象类和一个实现类,通过将实现类注入到抽象类中…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
