如果你也喜欢C#开发或者.NET开发,可以关注我,我会一直更新相关内容,并且会是超级详细的教程,只要你有耐心,基本上不会有什么问题,如果有不懂的,也可以私信我加我联系方式,我将毫无保留的将我的经验和技术分享给你,不为其他,只为有更多的人进度代码的世界,而进入代码的世界,最快捷和最容易的就是C#.NET,准备好了,就随我加入代码的世界吧!
简单工厂模式是一种创建型设计模式,主要用于根据不同的条件创建不同的对象。在C#中,简单工厂模式可以通过一个静态方法来实现。
首先,我们需要定义一个接口,表示要创建的对象的共同功能。例如,西游中太上老君会练丹、练器等等,那我们现在想让老君给我们练兵器,是不是得告诉他我想要练兵器,这时候我们新建一个兵器接口就相当于是告诉太上老君,我要练兵器了,你得准备好,里面包含一个方法,相当于告诉太上老君,你追后得给我一件兵器:
/// <summary>
/// 定义兵器接口
/// </summary>
public interface Arms
{
/// <summary>
/// 输出兵器
/// </summary>
void ExportWeapons();
}
然后,我们可以定义几个不同的兵器类来实现这个接口,这就相当于,太上老君能练什么兵器:
1、芭蕉扇
/// <summary>
/// 兵器:芭蕉扇
/// 继承兵器接口并实现输出兵器方法
/// </summary>
public class BananaFan : Arms
{
/// <summary>
/// 炼制芭蕉扇
/// </summary>
public BananaFan() {
Console.WriteLine("正在炼制芭蕉扇...");
}
/// <summary>
/// 实现兵器接口输出兵器方法
/// </summary>
public void ExportWeapons()
{
Console.WriteLine("芭蕉扇练成!芭蕉扇送你了...");
}
}
2、金刚琢
/// <summary>
/// 兵器:金刚琢
/// 继承兵器接口并实现输出兵器方法
/// </summary>
public class DiamondCarving:Arms
{
/// <summary>
/// 炼制金刚琢
/// </summary>
public DiamondCarving() {
Console.WriteLine("正在炼制金刚琢...");
}
/// <summary>
/// 实现接口输出兵器方法
/// </summary>
public void ExportWeapons()
{
Console.WriteLine("金刚琢练成!金刚琢送你了...");
}
}
3、金箍棒
/// <summary>
/// 兵器:金箍棒
/// 继承兵器接口并实现输出兵器方法
/// </summary>
public class GoldenHoopStick : Arms
{
/// <summary>
/// 炼制金箍棒
/// </summary>
public GoldenHoopStick() {
Console.WriteLine("正在炼制金箍棒...");
}
/// <summary>
/// 实现接口输出兵器方法
/// </summary>
public void ExportWeapons()
{
Console.WriteLine("金箍棒练成!金箍棒送你了..."); ;
}
}
接下来,我们是不是得让老君使用八卦炉来炼制这些兵器?,那我们就类包含一个静态方法,根据传入的条件返回对应的对象。例如,我们可以让八卦炉根据老君扔进去的材料,最后给我们制造什么样的兵器:
/// <summary>
/// 武器炉类
/// </summary>
public class WeaponryFurnace
{
/// <summary>
/// 根据材料,丹炉制造兵器
/// </summary>
/// <param name="material"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static Arms? GetArms(string material)
{
Arms? arms =null;
if (material.Equals("三昧真火"))
{
arms = new BananaFan();
Console.WriteLine("多谢屏幕前的你提供的三昧真火...");
}
else if (material.Equals("昆钢"))
{
arms = new DiamondCarving();
Console.WriteLine("多谢屏幕前的你提供的昆钢...");
}
else if (material.Equals("神物陶镕铁"))
{
arms = new GoldenHoopStick();
Console.WriteLine("多谢屏幕前的你提供神物陶镕铁...");
}
else {
throw new ArgumentException("材料不够,无法炼制...");
}
return arms;
}
}
最后,我们可以使用简单工厂来创建对象,例如,我给八卦炉三昧真火,那八卦炉会根据我给的三昧真火,给我一把芭蕉扇:
try
{
//给丹炉放材料
Arms arms = WeaponryFurnace.GetArms("三昧真火")!;
//输出兵器
arms.ExportWeapons();
}
catch (Exception ex)
{
//材料制造的兵器不在丹炉炼制范围或不给材料时
Console.WriteLine(ex.Message);
}
Console.ReadLine();
我们运行一下,看看,八卦炉给我们的结果是什么:
结果我们看到,输出的正是芭蕉扇,那如果我们给八卦炉的材料是昆钢呢?
try
{
//给丹炉放材料
Arms arms = WeaponryFurnace.GetArms("昆钢")!;
//输出兵器
arms.ExportWeapons();
}
catch (Exception ex)
{
//材料制造的兵器不在丹炉炼制范围或不给材料时
Console.WriteLine(ex.Message);
}
Console.ReadLine();
最后有人会说,我啥也不给,就像让八卦炉给我兵器:
try
{
//给丹炉放材料
Arms arms = WeaponryFurnace.GetArms("")!;
//输出兵器
arms.ExportWeapons();
}
catch (Exception ex)
{
//材料制造的兵器不在丹炉炼制范围或不给材料时
Console.WriteLine(ex.Message);
}
Console.ReadLine();
这里为什么会出现输出材料不够,无法炼制呢?
因为我在八卦炉类中,进行了判断,如果啥也没给,或者给的不是八卦炉能炼制的材料,那么八卦炉输出的就是材料不够,无法炼制的异常,然后再程序再通过try..catch..来捕捉八卦炉输出的异常信息:
通过太上老君八卦炉练兵器的案例,我们可以理解简单工厂模式,通过简单工厂模式我们可以根据不同的条件创建不同的对象,而不需要直接依赖于具体的类。这样可以降低耦合度,并且方便了后续的扩展和维护。
那我们现在可以总结一下,简单工厂模式的优缺点了:
首先我们说说简单工厂模式的优点:
1、封装对象的创建过程:通过简单工厂模式,可以将对象的创建过程封装起来,客户端只需要通过指定特定的参数,就可以获取所需的对象,而不需要了解对象的创建细节。
2、简化客户端代码:客户端只需要通过简单工厂类的静态方法或者工厂对象的方法来获取所需的对象,减少了客户端直接与具体产品类的耦合。
3、适应变化:如果需要添加新的产品类,只需要在简单工厂类中修改对应的逻辑即可,而无需修改客户端代码,符合开闭原则。
4、隐藏具体产品类的实现细节:简单工厂模式将具体产品类的实现细节隐藏在工厂类中,客户端只需要关心产品接口,无需关心具体实现。
5、方便管理对象的创建:通过简单工厂模式,可以将对象的创建集中管理,便于统一维护和控制。
然后我们说说简单工厂模式的缺点:
1、违背了开闭原则:当需要添加新的产品时,需要修改工厂类的代码,违背了开闭原则,会导致工厂类的职责过重。
2、增加了系统的复杂性:在简单工厂模式中,所有的产品都由一个工厂类来创建,当产品较多时,工厂类的代码会变得很复杂,难以维护和扩展。
3、不符合单一职责原则:工厂类负责创建所有产品,同时还要负责根据不同的参数选择创建不同的产品,违背了单一职责原则。
4、不支持扩展新产品:由于工厂类负责创建所有产品,当需要添加新的产品时,必须修改工厂类的代码,扩展性较差。
5、客户端需要了解所有的产品类:客户端必须知道所有产品的具体类名,不符合依赖倒置原则。
详细代码我已经放在资源里了: