工厂模式有什么缺点,工厂模式的优点和缺点
作者:ru4th 发布时间:2023-08-11 20:00 分类:生活问答 浏览:13
概述
工厂方法模式(FactoryMethod),定义一个创建产品对象的工厂接口,让工厂子类决定实例化哪一个产品类。我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”(可以通过反射克服该缺点)。
工厂方法模式是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
需求案例
我们先来看一看这样一个案例,小学生玩的四则运算,当客户输入两个数,然后输入一个操作符,获得结果!我们先用简单工厂写下逻辑代码,验证下简单工厂的缺点。
简单工厂代码
/// <summary>
/// 静态工作方法 实际上就是把创建对象的过程放到静态方法里面
/// </summary>
public class CalFactory
{
public static ICalculator GetCalculator(string oper)
{
ICalculator? calculator=;
switch (oper)
{
case "*":
calculator=new Mul;
break;
case "+":
calculator=new Add;
break;
case "-":
calculator=new Sub;
break;
case "/":
calculator=new Div;
break;
}
return calculator;
}
}
public interface ICalculator
{
double GetResult(double d1,double d2);
}
public class Add : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1+ d2;
}
}
public class Sub : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1-d2;
}
}
public class Mul : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1* d2;
}
}
public class Div : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1 / d2;
}
//C# 控制台调用
Console.WriteLine("简单工厂设计模式!");
Console.WriteLine("请输入操作数1");
var d1=Convert.ToDouble(Console.ReadLine);
Console.WriteLine("请输入操作数2");
var d2=Convert.ToDouble(Console.ReadLine);
ICalculator calculator=;
Console.WriteLine("请输入操作符");
string flag=Console.ReadLine;
calculator=CalFactory.GetCalculator(flag);
double reslut=calculator.GetResult(d1,d2);
Console.WriteLine(reslut);
这个需求的代码逻辑很简单,一看基本就会,我们主要说下简单工厂模式的优缺点;
优点:
1、简单工厂设计模式解决了客户端直接依赖具体对象的问题,客户端消除了创建对象的责任,仅仅承担使用的责任。简单工厂模式实现了对责任的分割;
2、简单工厂起到了代码复用的作用;
缺点:
1、系统扩展困难,一旦加入新功能,就必须要修改工厂逻辑。破坏了开闭原则;
2、简单工厂集合了多有创建对象的逻辑,一旦不能正常工作,会导致整个系统出问题;
工厂方法代码
还是上面的需求,我们定义一个创建对象的接口,让子类决定实例化哪一个类。
public interface ICalFactory
{
ICalculator GetCalculator;
}
public class MulFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Mul;
}
}
public class AddFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Add;
}
}
public class SubFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Sub;
}
}
public class DivFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Div;
}
}
public interface ICalculator
{
double GetResult(double d1, double d2);
}
public class Add : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1 + d2;
}
}
public class Sub : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1 - d2;
}
}
public class Mul : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1 * d2;
}
}
public class Div : ICalculator
{
public double GetResult(double d1, double d2)
{
return d1 / d2;
}
}
//C# 控制台调用
Console.WriteLine("请输入操作数1");
var d1=Convert.ToDouble(Console.ReadLine);
Console.WriteLine("请输入操作数2");
var d2=Convert.ToDouble(Console.ReadLine);
Console.WriteLine("请输入操作符");
string flag=Console.ReadLine;
ICalFactory? calFactory=;
switch (flag)
{
case "*":
calFactory=new MulFactory;
break;
case "+":
calFactory=new AddFactory;
break;
case "-":
calFactory=new SubFactory;
break;
case "/":
calFactory=new DivFactory;
break;
}
ICalculator calculator=calFactory?.GetCalculator;
var result=calculator.GetResult(d1, d2);
Console.WriteLine(result);
我们目前是使用了工厂方法设计模式来实现了需求,但能看到源码里面有一坨switch case,我们接下来通过反射处理switch case
没有switch case的工厂方法代码
public class OperFactory:Attribute
{
public string Oper { get; }
public OperFactory(string value)
{
Oper=value;
}
}
public class ReflectionFactory
{
//根据用户输入的操作符 返回一个对象
Dictionary<string, ICalFactory> dic=new Dictionary<string, ICalFactory>;
public ReflectionFactory
{
//拿到当前正在运行的程序集
Assembly assembly=Assembly.GetExecutingAssembly;
foreach (var item in assembly.GetTypes)
{
//IsAssignableFrom 表示item继承了ICalFactory或实现了ICalFactory
if (typeof(ICalFactory).IsAssignableFrom(item)&&!item.IsInterface)
{
OperFactory of=item.GetCustomAttribute<OperFactory>;
if (of !=)
{
//给键值对集合赋值
dic[of.Oper]=Activator.CreateInstance(item) as ICalFactory;
}
}
}
}
public ICalFactory GetFac(string s)
{
if (dic.ContainsKey(s))
{
return dic[s];
}
return ;
}
}
public interface ICalFactory
{
ICalculator GetCalculator;
}
[OperFactory("*")]
public class MulFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Mul;
}
}
[OperFactory("+")]
public class AddFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Add;
}
}
[OperFactory("-")]
public class SubFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Sub;
}
}
[OperFactory("/")]
public class DivFactory : ICalFactory
{
public ICalculator GetCalculator
{
return new Div;
}
}
//C# 控制台调用
ReflectionFactory reflectionFactory=new ReflectionFactory;
ICalFactory calFactory2=reflectionFactory.GetFac(flag);
var result2=calFactory2.GetCalculator.GetResult(d1, d2);
Console.WriteLine(result2);
总结
一个四则运算的需求,分别采用简单工厂和工厂方法实现,其实各有优缺点,使用哪种设计模式主要取决于自己的业务,有何疑问,欢迎交流。
- 上一篇:亚太5号高清,亚太五号
- 下一篇:郑州到武汉的高铁时刻表查询,郑州—武汉高铁
- 生活问答排行
- ***近发表
- ***新留言
-