C# 工厂模式

一、概述

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。在C#中,工厂模式通过定义一个公共接口或抽象类来创建对象,而具体的对象创建则由工厂类来实现。 工厂模式主要包含三个角色:

1. 抽象产品(Abstract Product):定义了产品的接口,具体产品需要实现这个接口。

2. 具体产品(Concrete Product):实现了抽象产品接口的具体类。

3. 工厂(Factory):负责创建具体产品的工厂类,通常包含一个创建产品的方法。

工厂模式的优点:

封装性:工厂模式隐藏了创建对象的细节,只需要知道创建对象的入口,而无需关注创建过程,它提供了把对象创建与对象使用分离的方法。
可扩展性:在工厂模式中,添加一个新的产品类型,只需要在工厂类中添加一个创建新产品的方法,不会影响到现有代码。
复杂对象的创建:工厂模式允许创建复杂的对象,把对象的创建过程和使用过程分开,可以使代码更容易维护。
解耦:工厂模式减少了客户端和实际产品类之间的耦合,可以独立更改实现,不会影响到其他部分。
总之,工厂模式是一种常用的对象创建型模式,具有封装性,可扩展性,复杂对象的创建和解耦等优点,适用于解决复杂对象创建问题。

工厂模式的缺点:

增加了系统复杂度:因为要把创建对象的过程抽象成接口,所以会增加系统复杂度。
父类被污染:由于工厂模式中的工厂类继承自抽象类,如果需要扩展父类的功能,可能会把父类的代码污染。
不符合开闭原则:工厂模式的实现要求修改工厂类代码,在添加新产品时可能需要修改工厂类,这不符合开闭原则。
总的来说,工厂模式虽然有一些缺点,但是它还是一种非常有用的设计模式,在很多情况下都可以帮助我们简化代码,提高代码质量。

上面这些介绍,几乎都是没什么用的文案,目的是为了做人类高质量文章,各位可以不看,当然你想看也没问题,只是看了和没看效果是一样的。

二、代码的实现

新建一个控制台项目,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 工厂模式
{internal class Program{static void Main(string[] args){Factory factory = new Factory();// 创建具体产品AIProduct productA = factory.CreateProduct("A");productA.Operation();  // 输出:具体产品A的操作// 创建具体产品BIProduct productB = factory.CreateProduct("B");productB.Operation();  // 输出:具体产品B的操作Console.ReadKey();}}// 抽象产品接口public interface IProduct{void Operation();}// 具体产品类Apublic class ConcreteProductA : IProduct{public void Operation(){Console.WriteLine("具体产品A的操作");}}// 具体产品类Bpublic class ConcreteProductB : IProduct{public void Operation(){Console.WriteLine("具体产品B的操作");}}// 工厂类public class Factory{public IProduct CreateProduct(string productType){switch (productType){case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new ArgumentException("无效的产品类型");}}}
}

运行:

工厂模式的代码也是非常的简单,这里就不做解析了,下面直接上一个案例吧。 

三、案例

由于工厂模式的主要作用是创建实例,那么就以公司的年会抽奖为案例吧,首先,随机设置一个抽奖人,然后由系统随机奖品,奖品有现金,手机,平板电脑,抽奖完成后,公布抽奖结果。

新建一个 Winform 项目,将项目的输入类型改为控制台输出,你可能会问:“这么简单的操作干嘛介绍啊”?你还别说,上次就有人问我,你这是控制台项目还是 Winform 项目,控制台从哪里出来的,也不写清楚?

界面就两个按钮,源码我就不上传了

新建一个类 Prize,加入下面代码,下面好几个类写在一起了,我也懒的分了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 工厂模式案例
{/// <summary>/// 奖品的类型/// </summary>public enum PrizeType{/// <summary>/// 现金/// </summary>Money,/// <summary>/// 手机/// </summary>MobilePhone,/// <summary>/// 平板电脑/// </summary>Ipad}/// <summary>/// 奖品/// </summary>public abstract class Prize{/// <summary>/// 数量/// </summary>public int Number { get; set; }/// <summary>/// 获奖人/// </summary>public string Awardee { get; set; }/// <summary>/// 奖品类型/// </summary>public PrizeType PrizeTypes { get; set; }/// <summary>/// 随机数/// </summary>public Random Randoms { get; private set; } = new Random();/// <summary>/// 操作/// </summary>public abstract void Operation();/// <summary>/// 设置获奖人/// </summary>/// <param name="Awardee"></param>public abstract void SetAwardee(string Awardee);}/// <summary>/// 现金/// </summary>public class Money : Prize{public override void Operation(){Number = Randoms.Next(100, 1000);PrizeTypes =  PrizeType.Money;Console.WriteLine("得到奖品 类型:{0},数量是:{1}", PrizeTypes, Number);}public override void SetAwardee(string awardee){Awardee = awardee;Console.WriteLine("当前奖品的获得者是:{0}", awardee);}}/// <summary>/// 手机/// </summary>public class MobilePhone : Prize{public override void Operation(){Number = Randoms.Next(1, 3);PrizeTypes = PrizeType.MobilePhone;Console.WriteLine("得到奖品 类型:{0},数量是:{1}", PrizeTypes, Number);}public override void SetAwardee(string awardee){Awardee = awardee;Console.WriteLine("当前奖品的获得者是:{0}", awardee);}}/// <summary>/// 平板电脑/// </summary>public class Ipad : Prize{public override void Operation(){Number = Randoms.Next(1, 3);PrizeTypes = PrizeType.Ipad;Console.WriteLine("得到奖品 类型:{0},数量是:{1}", PrizeTypes, Number);}public override void SetAwardee(string awardee){Awardee = awardee;Console.WriteLine("当前奖品的获得者是:{0}", awardee);}}public class Factory{public static Prize CreateProduct(PrizeType prizeType){switch (prizeType){case PrizeType.Money:return new Money();case PrizeType.MobilePhone:return new MobilePhone();case PrizeType.Ipad:return new Ipad();default:return null;}}private Factory() { }}
}

Form1 的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 工厂模式案例
{public partial class Form1 : Form{public Form1(){InitializeComponent();}//随机数private Random Randoms = new Random();//抽奖人列表private List<string> NameList = new List<string>() { "张三", "李四", "老王", "柱子", "狗剩", "铁蛋" };//当前的抽奖人private string Awardee = string.Empty;//奖品类型枚举的长度private int PrizeTypeCount = 0;private void Form1_Load(object sender, EventArgs e){PrizeTypeCount = System.Enum.GetNames(new PrizeType().GetType()).Length;}//抽奖人private void button1_Click(object sender, EventArgs e){int index = Randoms.Next(0, NameList.Count);Awardee = NameList[index];Console.WriteLine("当前的抽奖人是:{0}", Awardee);}//抽奖private void button2_Click(object sender, EventArgs e){if (string.IsNullOrEmpty(Awardee)){Console.WriteLine("请先确认抽奖人");return;}int index = Randoms.Next(0, PrizeTypeCount);PrizeType prizeType = (PrizeType)index;Prize prize = Factory.CreateProduct(prizeType);prize.Operation();prize.SetAwardee(Awardee);}}
}

运行:

这样一个简单的抽奖系统就实现了,有什么疑问或者建议,欢迎留言评论。

end

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

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

相关文章

在树莓派上搭建WordPress博客网站,并内网穿透发布到公网

目录 概述 安装 PHP 安装MySQL数据库 安装 WordPress 设置您的 WordPress 数据库 设置 MySQL/MariaDB 创建 WordPress 数据库 WordPress configuration 将WordPress站点发布到公网 安装相对URL插件 修改config.php配置 支持好友链接样式 定制主题 &#x1f388;个…

什么是异步编程?什么是回调地狱(callback hell)以及如何避免它?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 异步编程⭐ 回调地狱&#xff08;Callback Hell&#xff09;⭐ 如何避免回调地狱1. 使用Promise2. 使用async/await3. 模块化和分离 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…

adb使用总结

adb连接到模拟器 adb devices 打开模拟器&#xff0c;找到设置。 多次点击版本号&#xff0c;切换到开发者模式 搜索进入开发者选项 开启USB调试 此时在终端输入adb devices就连接上了 使用adb查看安卓手机架构 adb shell getprop ro.product.cpu.abi 进入安卓手机的shell …

drools8尝试(加单元测试)

drools8的maven模板项目里没有单元测试, 相比而言drools7有个非常好的test senorios 那就自己弄一个 文件是.http后缀的,写了个简单的例子如下 //测试交通违章 POST http://localhost:8080/Traffic Violation accept: application/json Content-Type: application/json{&q…

Unity 图片资源的适配

前言 最近小编做Unity项目时&#xff0c;发现在资源处理这方面和Android有所不同&#xff1b;例如&#xff1a;Android的资源文件夹res下会有着mipmap-mdpi&#xff0c;mipmap-hdpi&#xff0c;mipmap-xhdpi&#xff0c;mipmap-xxhdpi&#xff0c;mipmap-xxxhdpi这五个文件夹&a…

利用lammps模拟蓝宝石在水润滑环境下的抛光

一 问题描述 蓝宝石&#xff08;Al2O3&#xff09;由于其独特的晶体结构&#xff0c;优异的物理化学特性&#xff0c;被广泛应用于航空航天等领域。高精尖的应用领域要求蓝宝石具有纳米级的表面粗糙度以及严格可控的亚表面缺陷。影响超精密加工最终性能的因素主要集中在工件表…

Linux详解(包含Linux安装教程)

文章目录 Linux详解一、安装Linux操作系统VMware介绍安装虚拟机VMware下载centos 7系统安装centos 7系统 二、Linux基础命令Linux的目录结构Linux命令入门目录切换相关命令 cd、pwd相对路径、绝对路径和特殊路径符掌握通过mkdir命令创建文件夹文件操作命令touch、cat、more文件…

如何远程管理服务器详解

文章目录 前言一、远程管理类型二、远程桌面三、telnet 命令行远程四、查看本地开放端口 前言 很多公司是有自己的机房的&#xff0c;机房里面会有若干个服务器为员工和用户提供服务。大家可以想想&#xff1a;假设这家公司有上百台服务器&#xff0c;我们作为网络工程师&…

CGY-OS 正式开源!【软件编写篇】

上一篇文章&#xff1a;CGY-OS 正式开源&#xff01;_cgy091107的博客-CSDN博客 一、软件编写基础要求 在编写CGY-OS的应用程序之前&#xff0c;您需要&#xff1a; 1. 安装python3.10&#xff0c;配置好CGY-OS。 2.掌握python3的基本语法、lambda表达式、各种简单的数据结构。…

redis报错WRONGTYPE Operation against a key holding the wrong kind of value

在redis中我们一般存储string、list、hash类型的值&#xff0c;对应的方法分别为 db.StringGet(“key”)、db.ListRange、db.HashGetAll 如果取list类型值时使用了string的方法就会报WRONGTYPE Operation against a key holding the wrong kind of value错误。 redis-cli命令窗…

Git工作流

实际开发项目使用到的分支: main&#xff1a;生产环境&#xff0c;也就是你们在网上可以下载到的版本&#xff0c;是经过了很多轮测试得到的稳定版本。 release&#xff1a; 开发内部发版&#xff0c;也就是测试环境。 dev&#xff1a;所有的feature都要从dev上checkout。 fea…

Android kotlin 跳转手机热点开关页面和判断热点是否打开

Android kotlin 跳转手机热点开关页面和判断热点是否打开 判断热点是否打开跳转手机热点开关页面顺带介绍一些其他常用的设置页面跳转 其他热点的一些相关知识Local-only hotspot 参考 判断热点是否打开 网上方法比较多&#xff0c;我这边使用了通过WifiManager 拿反射的getWi…

【算法系列篇】前缀和

文章目录 前言什么是前缀和算法1.【模板】前缀和1.1 题目要求1.2 做题思路1.3 Java代码实现 2. 【模板】二维前缀和2.1 题目要求2.2 做题思路2.3 Java代码实现 3. 寻找数组的中心下标3.1 题目要求3.2 做题思路3.3 Java代码实现 4. 除自身以外的数组的乘积4.1 题目要求4.2 做题思…

常见前端面试之VUE面试题汇总八

22. Vue 子组件和父组件执行顺序 加载渲染过程&#xff1a; 1.父组件 beforeCreate 2.父组件 created 3.父组件 beforeMount 4.子组件 beforeCreate 5.子组件 created 6.子组件 beforeMount 7.子组件 mounted 8.父组件 mounted 更新过程&#xff1a; 1. 父组件 befor…

自然对数底e的一些事

自然对数底e的一些事 走的人多了就成了路 中国清代数学家李善兰&#xff08;1811—1882&#xff09; 凡此变数中函彼变数者&#xff0c;则此为彼之函数 自然对数底也是使用习惯 &#x1f349; 李善兰把function翻译为函数&#xff0c;函就是包含&#xff0c;含有变量&#xff…

【JVM 内存结构丨栈】

栈 -- 虚拟机栈 简介定义压栈出栈局部变量表操作数栈方法调用特点作用 本地方法栈&#xff08;C栈&#xff09;定义栈帧变化作用对比 主页传送门&#xff1a;&#x1f4c0; 传送 简介 栈是用于执行线程的内存区域&#xff0c;它包括局部变量和操作数栈。 Java 虚拟机栈会为每…

SpeedBI数据可视化工具:丰富图表,提高报表易读性

数据可视化工具一大作用就是能把复杂数据可视化、直观化&#xff0c;更容易看懂&#xff0c;也就更容易实现以数据驱动业务管理升级&#xff0c;因此一般的数据可视化工具都会提供大量图形化的数据可视化图表&#xff0c;以提高报表的易懂性&#xff0c;更好地服务企业运营决策…

[C++ 网络协议] 多进程服务器端

具有代表性的并发服务器端实现模型和方法&#xff1a; 多进程服务器&#xff1a;通过创建多个进程提供服务。✔ 多路复用服务器&#xff1a;通过捆绑并统一管理I/O对象提供服务。 多线程服务器&#xff1a;通过生成与客户端等量的线程提供服务。 1. 进程的概念及应用 1.1 什么…

windows中安装sqlite

1. 下载文件 官网下载地址&#xff1a;https://www.sqlite.org/download.html 下载sqlite-dll-win64-x64-3430000.zip和sqlite-tools-win32-x86-3430000.zip文件&#xff08;32位系统下载sqlite-dll-win32-x86-3430000.zip&#xff09;。 2. 安装过程 解压文件 解压上一步…

Mysql B+数索引结构

一、B树和B树区别 二、 B 树形成过程 三、页分裂过程 3.1 页分裂过程实例 3.1.1 原有数据1、3、5形成如下数据页 3.1.2 先新插入数据4&#xff0c;因为 页10 最多只能放3条记录所以我们不得不再分配一个新页&#xff1a; 新分配的数据页编号可能并不是连续的&#xff0c;也…