一、概述
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。在C#中,工厂模式通过定义一个公共接口或抽象类来创建对象,而具体的对象创建则由工厂类来实现。 工厂模式主要包含三个角色:
-
抽象产品(Abstract Product):定义了产品的接口,具体产品需要实现这个接口。
-
具体产品(Concrete Product):实现了抽象产品接口的具体类。
-
工厂(Factory):负责创建具体产品的工厂类,通常包含一个创建产品的方法。
工厂模式的优点:
封装性:工厂模式隐藏了创建对象的细节,只需要知道创建对象的入口,而无需关注创建过程,它提供了把对象创建与对象使用分离的方法。
可扩展性:在工厂模式中,添加一个新的产品类型,只需要在工厂类中添加一个创建新产品的方法,不会影响到现有代码。
复杂对象的创建:工厂模式允许创建复杂的对象,把对象的创建过程和使用过程分开,可以使代码更容易维护。
解耦:工厂模式减少了客户端和实际产品类之间的耦合,可以独立更改实现,不会影响到其他部分。
总之,工厂模式是一种常用的对象创建型模式,具有封装性,可扩展性,复杂对象的创建和解耦等优点,适用于解决复杂对象创建问题。
工厂模式的缺点:
增加了系统复杂度:因为要把创建对象的过程抽象成接口,所以会增加系统复杂度。
父类被污染:由于工厂模式中的工厂类继承自抽象类,如果需要扩展父类的功能,可能会把父类的代码污染。
不符合开闭原则:工厂模式的实现要求修改工厂类代码,在添加新产品时可能需要修改工厂类,这不符合开闭原则。
总的来说,工厂模式虽然有一些缺点,但是它还是一种非常有用的设计模式,在很多情况下都可以帮助我们简化代码,提高代码质量。
上面这些介绍,几乎都是没什么用的文案,目的是为了做人类高质量文章,各位可以不看,当然你想看也没问题,只是看了和没看效果是一样的。
二、代码的实现
新建一个控制台项目,代码如下:
cs
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();
// 创建具体产品A
IProduct productA = factory.CreateProduct("A");
productA.Operation(); // 输出:具体产品A的操作
// 创建具体产品B
IProduct productB = factory.CreateProduct("B");
productB.Operation(); // 输出:具体产品B的操作
Console.ReadKey();
}
}
// 抽象产品接口
public interface IProduct
{
void Operation();
}
// 具体产品类A
public class ConcreteProductA : IProduct
{
public void Operation()
{
Console.WriteLine("具体产品A的操作");
}
}
// 具体产品类B
public 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,加入下面代码,下面好几个类写在一起了,我也懒的分了
cs
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 的代码
cs
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