工厂设计模式后续之反射

引言

在上边博客中我提到的工厂设计模式中还存在switch case语句,原文链接:https://blog.csdn.net/weixin_72139050/article/details/134632062

我们这里使用的switch是根据客户的选择去返回对应的操作对象,但是我们的这个写法他是存在弊端的,这样不符合我们的依赖倒置原则,这里我们抽象依赖了细节,所以我们要做出对应的调整。

再上面博客的后面我们进行了优化,使用了工厂方法设计模式,在里面我们使用了抽象类,写了多个类来继承这个抽象类,让我们的细节依赖于抽象,减除了switch case ,但是随之问题产生,在我们的调用端产生了大量的switch case,我们依旧还在判断用户需要什么运算符.我们在这节需要干掉这段冗余代码

思考

 Console.WriteLine("请输入第一个操作数:");
 double d1 = Convert.ToDouble(Console.ReadLine());
 Console.WriteLine("请输入第二个操作数:");
 double d2 = Convert.ToDouble(Console.ReadLine());
 Console.WriteLine("请输入操作符:");
 string ock = Console.ReadLine();

 ICallFactory _Icoludoctor = null;

 switch (ock)
 {
     case "+":
         _Icoludoctor = new AddFactoay();
         break;
     case "-":
         _Icoludoctor = new JianFactoay();
         break;
     case "*":
         _Icoludoctor = new ChenFactoay();
         break;
     case "/":
         _Icoludoctor = new ChuFactoay();
         break;
 }

这段switch其实是描述了一种关系:运算符和我们具体工厂对象的对应关系。我们尝试换一种方式来实现这种对应关系

代码实现以及思路

我们通过Attribute来实现,在里面定义一个字符串,并且写一个构造函数,随后我们在每一个具体工厂对象类上面写上语句,然后我们程序运行起来之后,拿到这段关系,并且根据客户的操作返回对应的操作,这里我们通过反射来实现下面附上完整的代码

 static void Main(string[] args)
 {
     Console.WriteLine("请输入第一个操作数:");
     double d1 = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("请输入第二个操作数:");
     double d2 = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("请输入操作符:");
     string ock = Console.ReadLine();

     RefConrtilyFactory refConrtilyFactory = new RefConrtilyFactory();
     ICallFactory callFactory= refConrtilyFactory.GetFac(ock);
     Icoludoctor _ico= callFactory.GetIcoludoctor();
     double sum= _ico.GetResult(d1,d2);

     Console.WriteLine("答案是:" + sum);
     Console.ReadKey();
 }
 
 public class OperToFactory:Attribute
 {
     public string Opr { get; }
     public OperToFactory(string s)
     {
         Opr = s;
     }
 }

 public class RefConrtilyFactory
 {
     Dictionary<string, ICallFactory> dic = new Dictionary<string, ICallFactory>();

     public RefConrtilyFactory()
     {
         //拿到当前程序运行的程序集
         Assembly assembly = Assembly.GetExecutingAssembly();
         //我们只需要  AddFactoay JianFactoay ChenFactoay ChenFactoay这四个类
         foreach (var item in assembly.GetTypes())
         {
             //注意这里我们还要加判断,防止吧接口也加进来
             if (typeof(ICallFactory).IsAssignableFrom(item)&& !item.IsInterface)
             {
                 //我们拿Attribute
                 OperToFactory ofc= item.GetCustomAttribute<OperToFactory>();
                 if (ofc.Opr!=null)
                 {
                     dic[ofc.Opr] = Activator.CreateInstance(item) as ICallFactory;
                 }
             }
         }
     }

     //我们回传给客户端具体的哪个工厂对象
     public ICallFactory GetFac(string s)
     {
         if (dic.ContainsKey(s))
         {
             return dic[s];
         }
         return null;
     }
 }

 public interface ICallFactory
 {
     Icoludoctor GetIcoludoctor();
 }

 [OperToFactory("+")]
 public class AddFactoay : ICallFactory
 {
     public Icoludoctor GetIcoludoctor()
     {
         return new Add();
     }
 }

 [OperToFactory("-")]
 public class JianFactoay : ICallFactory
 {
     public Icoludoctor GetIcoludoctor()
     {
         return new Jian();
     }
 }

 [OperToFactory("/")]
 public class ChenFactoay : ICallFactory
 {
     public Icoludoctor GetIcoludoctor()
     {
         return new Chen();
     }
 }

 [OperToFactory("/")]
 public class ChuFactoay : ICallFactory
 {
     public Icoludoctor GetIcoludoctor()
     {
         return new Chu();
     }
 }


 /// <summary>
 /// 计算类的接口
 /// </summary>
 public interface Icoludoctor
 {
     //方法:返回最终结算的结果
     double GetResult(double d1, double d2);
 }

 public class Add : Icoludoctor
 {
     public double GetResult(double d1, double d2)
     {
         return d1 + d2;
     }
 }

 public class Jian : Icoludoctor
 {
     public double GetResult(double d1, double d2)
     {
         return d1 - d2;
     }
 }

 public class Chen : Icoludoctor
 {
     public double GetResult(double d1, double d2)
     {
         return d1 * d2;
     }
 }

 public class Chu : Icoludoctor
 {
     public double GetResult(double d1, double d2)
     {
         return d1 / d2;
     }
 }

我们干掉了switch,但是这样使我们的代码稍微有些许的复杂,但是让我们的代码更加正经了,哈哈,

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值